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

Example: I created business process where start signal is "delete record". After this signal I need to delete data from other object, that contains parameters contact and account from deleted record.

But as far as I can see, parameters form deleted record cannot be used as they are not existing or something like that:

    "Параметри процесу": [
        {
            "Параметр": "контраг",
            "Значення": {
                "Перед виконанням": "00000000-0000-0000-0000-000000000000",
                "Після виконання": "00000000-0000-0000-0000-000000000000"
            }
        },
        {
            "Параметр": "ртп зч",
            "Значення": {
                "Перед виконанням": "00000000-0000-0000-0000-000000000000",
                "Після виконання": "00000000-0000-0000-0000-000000000000"

 

Is it possible to work with parameters form deleted record via business process or it is possible only using coding?

Like 0

Like

2 comments

Make sure the properties of the start of the process has "run in background" unchecked. 

You absolutely right, thank you very much.

Show all comments

Hi Team, I trying to use Out-of-the-Box "Bulk email recipient (audience)" view as an Object signal to feed its data in another object. Two conditions I have applied are Record Added and Record Modified; but the process is not getting triggered when the record is getting added or updated in the "Bulk email recipient (audience)" view. How can we use this view to generate signal? Thanks

Like 0

Like

0 comments
Show all comments

Hello, community!

I’ve created a script that helps convert HTML text from a database into plain text.
 

To achieve this, you’ll need to add two libraries to the business process:


 

Then, use the following script task:



string texthtml = Get("texthtml");

if (string.IsNullOrWhiteSpace(texthtml)) {
   Set("DecodedHtmlText", string.Empty);
} else {
   // Remove HTML tags
   string text = Regex.Replace(texthtml, "<.*?>", string.Empty);

   // Decode HTML entities (e.g., & -> &)
   text = WebUtility.HtmlDecode(text);

   // Store the result in a business process variable
   Set("DecodedHtmlText", text);
}
 

return true;

* texthtml - parametr where our html text stored
* DecodedHtmlText - text type parametr to set text



I hope this will be useful!

 

Like 1

Like

Share

0 comments
Show all comments

Example 

Create the following business process: display a notification in the notification panel to an employee that was added to the list of participants in an activity. 

 

Business process diagram elements: 

  1. Incoming signal that adds an activity participant: when a new participant is added to the activity, activate the signal and start the business process. 
  2. Add data: create a notification in the "Notification" object to the participant. 

     

To do this: 

  1. Place the Signal element of the Initial events group on the diagram and call it "Participant added". Activate the element when a contact is added to the Participants expanded list of an activity. 
  2. Set up the signal parameters (Fig. 1): 
  3. Set "Activity participant" in the Object parameter. 
  4. Select "Record added" in the Which event should trigger the signal parameter. 
  5. Set "Participant = current contact" in the The added record must meet filter conditions area. 

Fig. 1 Signal element 

Fig. 1 Signal element 

  1. Place an Add data element of the System actions group between the Signal and Terminate elements and call it "Add notification." 
  2. Set up the element parameters (Fig. 2): 
  3. Select "Notification" in the Which object to add data to? parameter. 
  4. Select "One record" in the What is the data adding mode? parameter. 
  5. ClickAdd field in the Which column values to set? parameter. This opens a window. 
  6. Select "Created by," "IsRead," "NotificationType," "Object," "Source," "Time," "Title," "To," and "Unique caption Id" columns → Save
  7. SetCreated by to Lookup value → Supervisor
  8. SetIsRead to Boolean value → "False." 
  9. SetNotificationType to Lookup value → "Notification." 
  10. SetObject to Lookup value → "Activity." 
  11. SetSource to Lookup value → "Created by." 
  12. SetTime to Date and time → "Current date and time." 
  13. SetTitle to "You were added as a participant to an activity." 
  14. SetTo to "Current user contact." 
  15. SetUnique caption Id to Process parameter → Participant added → "Unique identifier of record." 

Fig. 2 Add data element 

 Fig. 2 Add data element
 

  1. Save the business process

 

As a result of the business process, every time a user contact is added as a participant to an activity, they will receive the corresponding message to the System messages sidebar of the notification panel. 

 

Like 3

Like

Share

0 comments
Show all comments

I want to read all records and then update them using a sub process, but there is a limit to reading records. how can I read all records and update them?

Like 0

Like

6 comments
Best reply

Hi Valdimir, 

 

Sure, first off all add a new boolean column on you account object, like processed, your main process like this

 

As I remember, there was a limit of 5000 records. If we need to process more, we create a script

Vladimir Sokolov,

You can add a column to track processed records and loop the read collection until there not unprocessed records, using the track column, for example. In this way, you have no limits

Julio.Falcon_Nodos,

Can you give me an example?

Julio.Falcon_Nodos,

As I remember, process cannot loop more than 5000 times either

Vladimir Sokolov,

Can you give me a sample script to update it?

Hi Valdimir, 

 

Sure, first off all add a new boolean column on you account object, like processed, your main process like this

 

Show all comments

I’m currently working on establishing a two-way connection between two applications in Creatio for adding and modifying records.
 

  1. One-Way Connection: I successfully created two business processes that allow for one-way synchronization of records.
  2. Two-Way Connection Issue: However, when I attempt to set up the two-way synchronization, it leads to the creation of multiple records in an infinite loop instead of just one record being created or updated.

 

Could anyone provide guidance on how to avoid this infinite loop in a two-way connection? Any insights on best practices for implementing two-way synchronization in Creatio would also be greatly appreciated.
 

I can provide screenshots of my setup for further clarification if needed. I followed the same process for the one-way connection as shown in the attached business process screenshot.

Like 0

Like

2 comments

Good day,

The issue you're encountering is related to the number of records being passed to the subprocess. Here are some suggestions for resolving this situation:

1. Add or adjust recursion trigger conditions:
   - For instance, if the trigger is based on changes to the `Contact.Age` field, consider adding a condition to ensure the age is not empty before initiating recursion.

2. Redesign the process to avoid recursion:
   - Replace recursion with iteration: Instead of processing records one by one with recursion, you can read and process multiple records in a sequential manner, ensuring that you do not handle a new record until the current one is fully processed.
   - Consolidate changes into a single process: Rather than reacting to various changes across different processes, use one process to handle all necessary changes at once. For example, initiate triggers in a single business process (BP) with all modifications related to a specific entity, which helps in minimizing and managing recursion more effectively.

It is crucial to first review the process logic with the above suggestions, as increasing the `MaximumBackgroundRecursionDepth` parameter could lead to application performance issues, such as slowing down or exhausting server memory, which might result in application restarts or stops.

In your system, the `MaximumBackgroundRecursionDepth` parameter is currently set to 100 (default is 100). The issue arises when the number of subprocess calls exceeds this value.

To address this problem, you may need to increase the `MaximumBackgroundRecursionDepth` parameter to accommodate all records, rather than only the initial 100.

Regards,
Orkhan

You need to have some way to determine the source of a record, so if the record came from the other object, you don't send it back again. 

For records added in "Data App", you'd flag those as coming from "Data App" when adding in "Info App", so the process that syncs from "Info App" back to "Data App" knows to exclude it from sending back to "Data App", etc.

If the records need to sync updates as well, you'd want to store the original record's Id value so you know where to update. You could then use the column storing the Id to know to exclude sending it back to add.

Ryan

Show all comments

I am currently developing an application where I need to add a "Sync Data" button to both the Accounts and Contacts sections. This button will trigger a Business Process that needs to work dynamically based on the context from which it is called.
 

The key requirement is to use a single, common Business Process for both Accounts and Contacts. In this process, I need to determine whether the button was clicked from the context of Accounts or Contacts, so the appropriate actions can be taken accordingly.
 

I understand that creating separate Business Processes for Accounts and Contacts could achieve this, but my goal is to have a unified process or function that can be reused across multiple entities.
 

I would greatly appreciate any guidance or suggestions on how to implement this in Creatio.

Thank you in advance for your assistance!

Like 0

Like

1 comments
Best reply

Create a boolean parameter "IsContact"(it's just an example, you could create any parameter ) and pass true if the button is clicked on contact page and false if it's clicked in any other place 

Create a boolean parameter "IsContact"(it's just an example, you could create any parameter ) and pass true if the button is clicked on contact page and false if it's clicked in any other place 

Show all comments

Hello.

I have a freedom UI FormPage, which may be opened from Business process (Open edit page element). I want to override Cancel button handler in such way that to cancel current business process. I need to know process id (SysProcessLog table) or process element id (SysProcessElementLog table). How could I obtain them in Freedom UI? For example in Classic UI edit page there was dedicated attribute called ProcessData. I looked through request.$context and didn't find anything similar.

 

Creatio version is 8.1.2

Like 0

Like

2 comments

Hello!

 

To find information, you can read the data from SysProcessData, more information which contains the interrelationship between the process instance and the subprocess, the relationship to the process scheme, the relationship to the process scheme element if the instance is a subprocess, and the current status of the process instance. Also, the internal state of the process is a snapshot of the values of the parameters at times when the process elements are executed.

 

Also, this article could be useful:

https://academy.creatio.com/docs/8.x/dev/development-on-creatio-platform/development-tools/external-ides/examples/develop-c-sharp-code-in-a-custom-project

 

Kyrylo Atamanenko,

Thanks for an answer. But to read all those information I need to know Id of an element being executed. For example in Classic UI it is obtained like 

this. 

const processElementUId = this.get("ProcessData").procElUId;

And the question is there analogue in Freeom UI page?

Show all comments

Hello,

 

I have a web service that generates a file. I need to attach that file to a record. I see there is an option to the Process File Component passing a File as parameter, but the Parameter is Expecting a IFileLocator. How can I use a script to create a IFileLocator from a full file path on Creatio Studio version 8.1? 

 

Thanks,

Jose

File attachments
Like 0

Like

2 comments
Best reply

Hello,

You should use a script task to work with files from the web service.

 

More details about the API file:



https://academy.creatio.com/docs/8.x/dev/development-on-creatio-platfor…

Hello,

You should use a script task to work with files from the web service.

 

More details about the API file:



https://academy.creatio.com/docs/8.x/dev/development-on-creatio-platfor…

Thanks Cherednichenko. Using the information provided I wrote the C# below to attach a generated file to a record.



public void AttachFile(string schemaName, Guid recordId, string fullFilePath) {

            /* Create a unique ID for the new file. */

            Guid fileId = Guid.NewGuid(); 

            /* Create a file locator for the new file. */

            var fileLocator= new EntityFileLocator("SysFile", fileId); 

            /* Get an IFile object for the new file. */ 

            IFile file = UserConnection.CreateFile(fileLocator); 

            /* There is no file metadata or file content in the available file storages. Specify the file name in the file metadata. */

            file.Name = (new System.IO.FileInfo(fullFilePath)).Name; 

            /* Set an attributes for the new file: */

            file.SetAttribute("RecordSchemaName", schemaName); 

            file.SetAttribute("RecordId", recordId);             

            /* Save the file metadata Do this BEFORE saving the content. */

            file.Save(); 

            using (var sourceStream = new FileStream( fullFilePath, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 4096, useAsync: true)) {

                file.Write(sourceStream, FileWriteOptions.SinglePart);            

            }

        }

Show all comments