Hi Creatio Community,

We're encountering a puzzling issue on a Freedom UI List Page (specifically, our Invoices_ListPage) when trying to run a business process (IWVoid_API_POST) using a custom JavaScript handler. The goal is to test the business process by explicitly passing a hardcoded InvoiceId, as requested for a specific testing scenario where the button is not on the individual record's form page.

Our Setup:

  1. The Button (Menu Item on List Page's ActionButton):

    We've added a crt.MenuItem to the ActionButton on our Invoices_ListPage. This menu item is intended for testing and is configured to trigger a custom handler:

    JSON

     

    // In viewConfigDiff of Invoices_ListPage.js
    {
        "operation": "insert",
        "name": "TargetVoidButton", //
        "values": {
            "type": "crt.MenuItem",
            "caption": "Test Void BP (Hardcoded ID)", 
            "icon": "debug-icon",
            "visible": true,
            "clicked": {
                "request": "crt.HandleButtonClickRequest",
                "params": {
                    "buttonName": "RunTargetVoidProcessHandler" 
                }
            }
        },
        "parentName": "ActionButton",
        "propertyName": "menuItems",
        "index": 3 
    }
  2. The Handler (in handlers array of Invoices_ListPage.js):

    This handler is designed to run the IWVoid_API_POST process with a specific, hardcoded InvoiceId.

    JavaScript

     

    // In handlers array of Invoices_ListPage.js
    {
        request: "crt.HandleButtonClickRequest",
        handler: async (request, next) => {
            if (request.buttonName === "RunTargetVoidProcessHandler") { 
                console.log("RunTargetVoidProcessHandler triggered.");
                Terrasoft.showInformation("Test: Running process with hardcoded ID. Check console.");
     
                const processName = "IWVoid_API_POST";
                const hardcodedInvoiceIdForTest = "3c2b6d9f-4c1e-4364-99f2-53956562b606"; 
                const parameterNameInProcess = "InvoiceId"; 
     
                console.log(`Test: Attempting to run BP '<span class="math-inline">\{processName\}' with EXPLICIT HARDCODED ID '</span>{hardcodedInvoiceIdForTest}' for parameter '${parameterNameInProcess}'.`);
     
                try {
                    const response = await request.$context.executeRequest({
                        type: "crt.RunBusinessProcessRequest",
                        params: {
                            processName: processName,
                            processParameters: {
                                [parameterNameInProcess]: hardcodedInvoiceIdForTest
                            },
                            saveAtProcessStart: false, 
                            showNotification: true 
                        }
                    });
     
                    console.log("Test: BP execution request completed. Response:", response);
     
                    if (response && response.success === true && response.processId && response.processId !== '00000000-0000-0000-0000-000000000000') {
                        const successMsg = `Test: BP '${processName}' (ID: ${response.processId}) initiated. Check Process Log.`;
                        console.log(successMsg);
                        request.$context.showInformationDialog?.(successMsg);
                    } else {
                        let errorMsg = `Test: Failed to start BP '${processName}'.`;
                        let serverDetails = (response && response.errorInfo && response.errorInfo.message) ? response.errorInfo.message : "Details unavailable or process not found (zero ID / success:false).";
                        errorMsg += ` ${serverDetails}`;
                        console.error(errorMsg, "Full response:", response);
                        request.$context.showErrorDialog?.(errorMsg);
                    }
                } catch (error) {
                    console.error(`Test: Exception for BP '${processName}':`, error);
                    let exceptionMsg = (error instanceof Error && error.message) ? error.message : "Client-side exception.";
                    if (error.errorInfo && error.errorInfo.message) {
                        exceptionMsg = error.errorInfo.message;
                    }
                    request.$context.showErrorDialog?.(`Test: Error triggering BP: ${exceptionMsg}`);
                }
                return; 
            }
            return next?.handle(request);
        }
    }

The Problem:

When we click the "Test Void BP (Hardcoded ID)" menu item, the handler triggers, and the client-side logs show the crt.RunBusinessProcessRequest is being prepared correctly with processName: "IWVoid_API_POST" and the hardcoded InvoiceId.

However, the server responds with:

{
  processId: '00000000-0000-0000-0000-000000000000', 
  processStatus: 0, 
  resultParameterValues: null, 
  executionData: null, 
  success: false, 
  errorInfo: {
    errorCode: "ItemNotFoundException",
    message: "Item process schema \"\" not found.", // Note the empty quotes for schema name
    stackTrace: null
  }
}

The key error is <strong>Item process schema "" not found.</strong>

What We've Tried:

  • Confirmed the schematic name (Code) of our business process is indeed IWVoid_API_POST.
  • Confirmed the input parameter in the BP designed to take the ID is named InvoiceId.
  • Repeatedly saved, compiled, and published the IWVoid_API_POST business process and ensured it's marked as "Active."
  • Checked the package containing the process for any errors and recompiled the package.
  • Performed thorough browser cache clearing and hard refreshes (Ctrl+F5).
  • We also have another menu item on the same list page ("VoidInvoice") that uses a declarative crt.RunBusinessProcessRequest with processRunType: "ForTheSelectedRecords" and parameterMappings: { "InvoiceId": "Id" }. When a record is selected and this menu item is clicked, it successfully starts the <strong>IWVoid_API_POST</strong> process (verified in Creatio Process Log with a non-zero instance ID). This makes the current error even more puzzling.

Our Questions for the Community:

  1. Why would the ProcessEngineService report Item process schema "" not found (with empty quotes for the schema name) when the processName: "IWVoid_API_POST" is explicitly and correctly provided in the params of crt.RunBusinessProcessRequest from our custom handler?
  2. Is there any known difference in how process names are resolved or how schemas are looked up by the server when crt.RunBusinessProcessRequest is invoked programmatically from a handler with processParameters explicitly set (using a hardcoded ID), versus when it's invoked declaratively with processRunType: "ForTheSelectedRecords" or processRunType: "ForTheSelectedPage"?
  3. Are there any deeper caching mechanisms (server-side, metadata) or specific registration steps for business process schemas that we might be missing, which could lead to this behavior only for the explicit parameter call?
  4. Has anyone encountered a similar situation where a process is findable/runnable via one SDK invocation method (declarative, context-based) but not another (programmatic handler, explicit parameters) from the same Freedom UI page type?

We are unable to access detailed server-side application logs for this specific environment at the moment, which is hampering deeper diagnosis from our end.

Any insights, suggestions, or similar experiences would be greatly appreciated!

Thank you!

Like 0

Like

1 comments

Hi Andrew,

The behavior you described where the system responds with Item process schema "" not found despite providing the correct process name can occur when certain required parameters are missing during the execution of a business process from a handler. Specifically, when using crt.RunBusinessProcessRequest from a crt.HandleButtonClickRequest handler, the backend expects additional context that is typically provided automatically during declarative invocations.

To ensure that the process schema is correctly identified and executed, it is important to explicitly include the processRunType, the recordIdProcessParameterName. These parameters provide the necessary linkage between the UI context and the process runtime.

Below is an example of a working implementation where a business process is successfully launched from a button on a Freedom UI page. The button configuration and handler explicitly define all required fields:

Button configuration:
{
 "operation": "insert",
 "name": "Button_7y0uys4",
 "values": {
   "layoutConfig": {
     "column": 1,
     "row": 2,
     "colSpan": 1,
     "rowSpan": 1
   },
   "type": "crt.Button",
   "caption": "#ResourceString(Button_7y0uys4_caption)#",
   "color": "outline",
   "disabled": false,
   "size": "large",
   "iconPosition": "only-text",
   "visible": true,
   "clicked": {
     "request": "crt.HandleButtonClickRequest",
     "params": {
       "buttonName": "RunTestProcess",
       "processName": "UsrTestProcessInvoiceAdded",
       "processRunType": "ForTheSelectedPage",
       "recordIdProcessParameterName": "InvoiceId"
     }
   }
 },
 "parentName": "SideAreaProfileContainer",
 "propertyName": "items",
 "index": 1
}

Handler logic:
{
 request: "crt.HandleButtonClickRequest",
 handler: async (request, next) => {
   if (request.buttonName === "RunTestProcess") {
     const handlerChain = sdk.HandlerChainService.instance;
     const result = await handlerChain.process({
       type: "crt.RunBusinessProcessRequest",
       processName: "UsrTestProcessInvoiceAdded",
       processRunType: "ForTheSelectedPage",
       recordIdProcessParameterName: "InvoiceId",
       $context: request.$context
     });

     if (result.success) {
       console.log("The process was successfully executed!");
     } else {
       console.log("Exception: " + (result.errorInfo?.message || "Unknown issue"));
     }

     return;
   }
   return next?.handle(request);
 }
}

Answers to your questions:

1. Why would the ProcessEngineService report Item process schema "" not found (with empty quotes for the schema name) when the processName: "IWVoid_API_POST" is explicitly and correctly provided in the params of crt.RunBusinessProcessRequest from our custom handler? 

- This usually happens if processRunType, recordIdProcessParameterName are not passed when triggering the process from a handler. These parameters are essential for correctly resolving the process schema in the runtime context.

2. Is there any known difference in how process names are resolved or how schemas are looked up by the server when crt.RunBusinessProcessRequest is invoked programmatically from a handler with processParameters explicitly set (using a hardcoded ID), versus when it's invoked declaratively with processRunType: "ForTheSelectedRecords" or processRunType: "ForTheSelectedPage"? 

- Yes. In declarative calls, Creatio automatically adds all required metadata. In programmatic calls (handlers), this metadata must be passed manually, especially processRunType and recordIdProcessParameterName.

3. Are there any deeper caching mechanisms (server-side, metadata) or specific registration steps for business process schemas that we might be missing, which could lead to this behavior only for the explicit parameter call? 

- In general, no special registration is required if the process is active and compiled. However, if the process was recently created or modified, reload the page and make sure that the changes in the process were saved.

4. Has anyone encountered a similar situation where a process is findable/runnable via one SDK invocation method (declarative, context-based) but not another (programmatic handler, explicit parameters) from the same Freedom UI page type?

- Yes, this can happen if the required context parameters are not included in the handler call. Declarative calls handle this automatically, whereas in handlers you must explicitly set them.

Show all comments

How can i add new page parameter in pre-configured page in default creatio pre-configured page in freedom ui

Like 1

Like

2 comments

In the page designer, expand page parameters and add them there

Ryan

Hi Ryan Farley,

i just want to display the existing data source and the parameter, can i add to the parameter on the pre-configured page with the existing default parameter?

because in here i have most of the parameter but,

on the pre-configured page i just have some of them

Show all comments

Hello Community,

We have created a button in Leads_FormPage that opens AddTaskMiniPage

Code in Leads_FormPage that opens the AddTaskMiniPage

  {
        request: "usr.OpenTaskModalPageRequest",
        handler: async (request, next) => {
            const handlerChain = sdk.HandlerChainService.instance;
            await handlerChain.process({
                type: 'crt.OpenPageRequest',
                schemaName: 'AddTaskMiniPage',
                $context: request.$context,
                scopes: [...request.scopes]
            });
            return next?.handle(request);
        }
    }		,

 

Our end goal: We want that upon the Activity is created (Save button clicked in AddTaskMiniPage) the value of 'Start' field in AddTaskMiniPage, is copied to another Date field in the Leads_FormPage.

How can this be acheived?

Regards

Sasor

Like 0

Like

3 comments

Hello Sasori,

You can try using BP for this case. For example, when you save a record in a mini page, you also run a business process that will update a value in your lead record. You pass date value to the BP and set (update) relevant field in the lead record. 
 

An easy way to accomplish this is to just use a process with a signal of Activity added with Type=Task, Category=To do, Lead is filled in. Then update the lead with the date. If you have live data updates enabled for the Lead object you'll even see the screen refresh with the value. 

Ryan

Ryan Farley,

Thank you for your input! However, the challenge with this approach is that there might be multiple activities associated with a single Lead that have this specific configuration (Type = Task, Category = To Do, Lead is filled in).

Would it be possible to handle this scenario directly via the Frontend instead?

Looking forward to your thoughts!

Show all comments

Hello!

I have this code that I want to edit with a new process.

 

ApproveHO: {

                    "value":"77e55977-070b-4af3-92a4-87014b4acff6", //New df53924b-c968-4421-85e2-406a23efd254

                    "displayValue":"Approve HO",

                    "parameterUId":"670a33d3-fba7-4f33-bec5-abbf254c8038" //

                },

 

Does anybody know where I can find parameterUId? I can find the id of the process, but not "parameterUId".

Thank you!

Like 0

Like

1 comments

Hello,

 

It's hard to understand what should be done unfortunately. If you need to find the 670a33d3-fba7-4f33-bec5-abbf254c8038 Id in the schemas try searching the schema using:

 

1) MetaData column from the SysSchema table

2) Source column from the SysSchemaSource table

3) Content column from the SysSchemaContent column

Show all comments

Hello

 

I wanted to add my own Customer Parameters to a Product (E.g. Standard Destination, Business Line).

 

 

I added them in the "Parameters" lookup like the base ones. But none of them can appear. In the picture below you can see "Resident", a parameter that was put but before in the same way.

 

 

Is there another place where I should add them?

 

Thank you!

Like 0

Like

1 comments

Hello!

 

The product has a category and a type. The customer parameter field uses them to filter the parameters.

 

You need to create an additional record in the "DefSpecification" table ("Default Feature" object).

1. To do this, you can create a new lookup in the lookup section, based on the "Default Feature" object.

2. When you open it, please add a new record, specifying any name, selecting the product's category and the product's type.

3. In the "Feature" column you need to select the custom feature you have added.

 

After that, if the category and type in the "Default Feature" lookup are matching with your product, you will see your custom parameter in the selection list!

 

Best regards,

Max.

Show all comments

Hello!

 

I added my custom parameters, Client Category & Standard Destination in for each Product and I would like to filter by them. 

 

 

In the Opportunity page I have the "Product" field.

 

Does anybody know how I can filter the product based on the Custom Parameters that I have? I 

 

Thank you!

Like 0

Like

1 comments

Hello!

 

Here are a few points that should be helpful:

 

1. The product catalog is not displayed in Opportunity. There is no logic yet that would automatically fill the Opportunity page from the product catalog according to the given parameters in the Opportunity. You would need to configure a business process, you can use the product selection functionality. For this, there is an action in the "Products" section or a pre-configured page that can be used in the business process.



2. If you still need to set up a filter on the product catalog section, see the example here:

3. In Sales there are the following details: "Parameter" on the "Opportunity details" tab, "Products" on the "Products" tab. These details work according to the contents of the "Customer needs" lookup. If the value of such needs is selected for Opportunity, for which the parameters are preset - they will be automatically added to this detail. If products are added there, they will be available for selection in the "Opportunity Product" detail. You can modify this lookup in the Leads section (it works the same way for leads), in the "Setup customer needs" action.

Show all comments

Hi Community!!!

I used built in web service configuration to configure an integration with third party app.

The JSON that third party app receives looks like this:

{

  "url": "https://test",

  "events": ["a","b"]

}



The configuration for the events parameter into web service is as shown in the image below:

My issue is when I try to call this Web Service/Method from a Business Process. I cannot send the correct values for the events parameter. I tried several options for example: read a lookup values, create list or collection in a script task, etc. but I couldn't achive the goal.

The image below shows how the parameter is requested on the business process:

 

Below I show the trace with an example of the values I try to pass to the paramter:



"Parameter": "Events",

            "Value": {

                "Before execution": [

                    {

                        "Name": "invitee.created"

                    },

                    {

                        "Name": "invitee.canceled"

                    }

                ],

 

Any recomendation?

Regards.

 

 

 

 

Like 0

Like

3 comments

Hello,

You can send  your values using a collection.

The values of collection parameters of a [ Call web service ] process element can be mapped to the nested parameters of another collection of a [ Read data ] or [ Call web service ] process element .Additionally, each item of the collection can be mapped to an individual subprocess instance in the [ Subprocess ] element.



 

You can find more detailed information on the academy website:

https://academy.creatio.com/docs/user/bpm_tools/process_elements_refere…

Cherednichenko Nikita,

Thank you! I tried it but the result is something like this:

 

[

                    {

                        "Name": "invitee.created"

                    },

                    {

                        "Name": "invitee.canceled"

                    }

                ],

The expected value is 

[invitee.created","invitee.canceled"]

 

How can I achive this?

Regards.

Hello,

The code

[

                    {

                        "Name": "invitee.created"

                    },

                    {

                        "Name": "invitee.canceled"

                    }

],

Is seen like : [{"Name": "invitee.created"}, {"Name": "invitee.canceled"}].

But, in your case, I believe you can use the parameter value "Collection of values"

 

Show all comments

Hello community,

 

We have a use case where some business logic has been implemented as a business process and the output of it is set to 2 business process parameters. We need to trigger this BP from source code and read the output parameters after execution of the process. The execution part is straight forward. The reading of parameters is not. 

 

I went through various articles/questions on the community related to these. But most of them only talk about executing a process by setting parameters and not reading parameters after execution. Request some assistance.



I also went through the IProcessExecutor documentation here and it permits to retrieve one result parameter. What if I need to read more than 1 parameter at the end of the business process execution?? Is there any other way to execute a BP from server side code and get the output parameter?



Note - I am aware that the Business process can be executed via a Http call to the ProcessEngineService and output parameters retrieved via the ResultParameterName query parameter. This is not a viable option for us. Additionally, it only permits one ResultParameterName and not reading multiple business process parameters.

Like 0

Like

4 comments
Best reply

Hello,

 

You can use this example to receive parameters: 

// getting UserConnectionUserConnection userConnection = GetUserConnection();
// getting  IProcessExecutor
IProcessExecutor processExecutor = userConnection.ProcessEngine.ProcessExecutor;
// List of input parameters
var inputParameters = new Dictionary&lt;string, string&gt; {
    ["ProcessSchemaParameter1"] = "Value1",
    ["ProcessSchemaParameter2"] = "Value2"
};
//  List of output parameters
var resultParameterNames = new string[] {
    "ProcessSchemaParameter3",
    "ProcessSchemaParameter4"
};
string processSchemaName = "processSchemaName";
Guid processSchemaUId = Guid.Parse("00000000-0000-0000-0000-000000000000");
 
// Run the process by schema name and forwarding output parameters
ProcessDescriptor processDescriptor = processExecutor.Execute(processSchemaName, resultParameterNames);
// Run the process by schema UId and forwarding output parameters
ProcessDescriptor processDescriptor = processExecutor.Execute(processSchemaUId, resultParameterNames);
 
//  Run the process by schema name with forwarding input and output parameters
ProcessDescriptor processDescriptor = processExecutor.Execute(processSchemaName, inputParameters, resultParameterNames);
// Run the process by schema UId with forwarding input and output parameters
ProcessDescriptor processDescriptor = processExecutor.Execute(processSchemaUId, inputParameters, resultParameterNames);

You can also get values of the resulting parameters by accessing the ResultParameterValues property of the IReadOnlyDictionary <string, object> type of the ProcessDescriptor class: 

ProcessDescriptor processDescriptor = processExecutor.Execute("processSchemaName", inputParameters, resultParameterNames);
object parameter3Value = processDescriptor.ResultParameterValues["ProcessSchemaParameter3"];
if (processDescriptor.ResultParameterValues.TryGetValue("ProcessSchemaParameter4", out object parameter4value)) {
    Console.Log(parameter4value);
}

Please note that such process will always be run in not-background mode and you will be able to receive several parameters only from version 7.17.1. 

 

Best regards,

Angela

Hello,

 

You can use this example to receive parameters: 

// getting UserConnectionUserConnection userConnection = GetUserConnection();
// getting  IProcessExecutor
IProcessExecutor processExecutor = userConnection.ProcessEngine.ProcessExecutor;
// List of input parameters
var inputParameters = new Dictionary&lt;string, string&gt; {
    ["ProcessSchemaParameter1"] = "Value1",
    ["ProcessSchemaParameter2"] = "Value2"
};
//  List of output parameters
var resultParameterNames = new string[] {
    "ProcessSchemaParameter3",
    "ProcessSchemaParameter4"
};
string processSchemaName = "processSchemaName";
Guid processSchemaUId = Guid.Parse("00000000-0000-0000-0000-000000000000");
 
// Run the process by schema name and forwarding output parameters
ProcessDescriptor processDescriptor = processExecutor.Execute(processSchemaName, resultParameterNames);
// Run the process by schema UId and forwarding output parameters
ProcessDescriptor processDescriptor = processExecutor.Execute(processSchemaUId, resultParameterNames);
 
//  Run the process by schema name with forwarding input and output parameters
ProcessDescriptor processDescriptor = processExecutor.Execute(processSchemaName, inputParameters, resultParameterNames);
// Run the process by schema UId with forwarding input and output parameters
ProcessDescriptor processDescriptor = processExecutor.Execute(processSchemaUId, inputParameters, resultParameterNames);

You can also get values of the resulting parameters by accessing the ResultParameterValues property of the IReadOnlyDictionary <string, object> type of the ProcessDescriptor class: 

ProcessDescriptor processDescriptor = processExecutor.Execute("processSchemaName", inputParameters, resultParameterNames);
object parameter3Value = processDescriptor.ResultParameterValues["ProcessSchemaParameter3"];
if (processDescriptor.ResultParameterValues.TryGetValue("ProcessSchemaParameter4", out object parameter4value)) {
    Console.Log(parameter4value);
}

Please note that such process will always be run in not-background mode and you will be able to receive several parameters only from version 7.17.1. 

 

Best regards,

Angela

Angela Reyes,

Thank you Angela for the inputs

Hi not sure whether this thread still seen 

I am using following code 
ProcessDescriptor processDescriptor = processExecutor.Execute("processSchemaName", inputParameters, resultParameterNames); 

While the BP was triggered but i see the InputParameter is null. What i am missing -- any working code. 

            var inputParameters = new Dictionary<string, string> {
                  ["InputParam"] = "Parameter sent from the Virtual Object"
            } ;

           var resultParameterNames = new string[] { "OutPutParam"};
         

           IProcessEngine processEngine = _userConnection.ProcessEngine;
           IProcessExecutor processExecutor = processEngine.ProcessExecutor;


          ProcessDescriptor processDescriptor = processExecutor.Execute("HC_ReadVirtualObject", inputParameters, resultParameterNames);
          object  jsonObj = processDescriptor.ResultParameterValues["OutPutParam"];

 

Sarangarajan Tirucherai,

Hello,

A couple of questions first:

  1. This is only the InputParameter which is null or the OutPutParam as well?
  2. How do you use this InputParameter inside the business process? Do you use it in some formula or simply for filtering or how is it done?

Thank you!

Show all comments

we have a custom button on the section page that triggers a process.

When the business process returns to the section page code, is it possible to capture a return parameter from the process  ? how ?

Like 0

Like

1 comments

The issue is that the process will execute asynchronously. The only way to get the value back from the process is, instead of using it as an output param, to send it as a message using a script task in the process that you will retrieve with client-side code on the page. 

You can see an article outlining how to do this here: https://customerfx.com/article/sending-a-message-from-server-side-c-to-…

 

Basically, at the end of your process, you'll add a script task. In that script task you'll get the param value, then send it as a message (as outlined in the article). Then, in your page code, you'll listen for that message, check to make sure it's the message sent from your process, and then read the value and do whatever is needed with it.

Ryan

Show all comments

What is the data type to read a date parameter in a script task ?

 

var myVar = Get<????>("MyParameter") 

 

Like 0

Like

3 comments
Best reply

You would use:

 

var myDate = Get<DateTime>("MyDateParam");

 

A date only param is still just a .NET DateTime struct just like a Date and Time value in Creatio -  A date only will just have a zero time value (so the value would be something like "Oct 29, 2020 00:00:00")

Ryan

You would use:

 

var myDate = Get<DateTime>("MyDateParam");

 

A date only param is still just a .NET DateTime struct just like a Date and Time value in Creatio -  A date only will just have a zero time value (so the value would be something like "Oct 29, 2020 00:00:00")

Ryan

Hi Ricardo,

 

Indeed, you can use the solution suggested above. However, please note that you'll get the date in a server timezone.

var myDate = Get<DateTime>("MyDateParam");

 

There is an option to pass a string as usual and parse it then. Also, you can pass ticks and use the result. For example: 

long ticks = Get<long>("MyDateParameterInTicks");

new DateTime(ticks, DateTimeKind.Utc).ToLocalTime();

 

Please read more about ticks property by the link below:

https://docs.microsoft.com/en-us/dotnet/api/system.datetime.ticks?view=…

 

Regards,

Anastasiia

Anastasiia Markina,

That is good to know, thanks Anastasiia.

Show all comments