Rushi Savarkar
Mega Sage
Mega Sage

Requirement Overview:
In ServiceNow Lifecycle Events, activity sets can occasionally become stuck in an Awaiting Trigger state, preventing the progression of HR cases. The objective was to develop a Fix Script to manually retrigger these activity sets for specific HR services or cases.
A critical challenge identified during initial implementation was the creation of duplicate tasks (RITMs). This occurred because the script initialized new workflow contexts while the original, stuck contexts remained active. The requirement evolved to include a mechanism that ensures only one active workflow context exists by cancelling the old one during the retrigger process.
Solution
The solution utilizes a Fix Script that retrieves configuration via system properties and iterates through activity set contexts to restart the workflow and clean up legacy contexts.

 

var activitySetId = gs.getProperty("sn_hr_le.retrigger_activity_set_sys_id");
var hrCaseId = gs.getProperty("sn_hr_le.retrigger_activity_set_le_case_sys_id");
var hrServiceId = gs.getProperty("sn_hr_le.retrigger_activity_set_hr_service_sys_id");

// Define the delimiter for splitting the sys_id string
var delimiter = /\s*[;,\n]+\s*/gi;

// Split the activity set ID string and trim any whitespace
var activitySetSysIds = activitySetId.trim().split(delimiter);

// Loop through each activity set sys_id
for (var i = 0; i < activitySetSysIds.length; i++) {
    var activitySetSysId = activitySetSysIds[i];
    var actContextGr = new GlideRecord('sn_hr_le_activity_set_context');
    if (hrCaseId != '') {
        // Add query filter based on the hr_case_id and activity_set_sys_id
        actContextGr.addEncodedQuery('state=awaiting_trigger^hr_case.hr_service=' + hrServiceId +'^activity_set=' + activitySetSysId + '^hr_case.sys_id=' + hrCaseId);
    }else{
        actContextGr.addEncodedQuery('state=awaiting_trigger^hr_case.hr_service=' + hrServiceId +'^activity_set=' + activitySetSysId );
    }
    // Execute the query
    actContextGr.query();
    // Iterate through each resulting record
    while (actContextGr.next()) {
        // Retrieve the associated HR case record
        var caseGr = new GlideRecord('sn_hr_le_case');
        if (caseGr.get(actContextGr.hr_case)) {

            // Initialize the workflow script include
            var workflowScriptInclude = new global.Workflow();
            var workflowContextGr = actContextGr.workflow_context.getRefRecord();

            // Prepare activity test inputs from the workflow context scratchpad, if available
            var activityTestInputs;
            if (!gs.nil(workflowContextGr.getValue('scratchpad'))) {
                var scratchpad = JSON.parse(workflowContextGr.getValue('scratchpad'));
                activityTestInputs = scratchpad['activityTestInputs'];
            }

            // Start the workflow
            workflowScriptInclude.startFlow('4396613053d622003066a5f4a11c0875', caseGr, caseGr.operation(), {
                activity_set_id: actContextGr.activity_set,
                item_id: caseGr.sys_id,
                subject_person_id: caseGr.subject_person,
                parent_table: caseGr.sys_class_name,
                is_resume: true,
                activity_test_inputs: activityTestInputs
            });

            //cancel old context
            workflowScriptInclude.cancelContext(workflowContextGr);
        } else {
            gs.info("HR Case not found for activity set context: " + actContextGr);
        }
    }
}

Fix Script Code Explanation

Get configuration values from system properties (sys_ids of activity sets, HR cases, HR service).

Parse the activity set IDs (can be multiple, separated by comma, semicolon, or newline).
For each activity set:

  • Query the sn_hr_le_activity_set_context table to find activity sets in the awaiting_trigger state.

  • For each result:
    • Get the related HR case.
    • Start the activity set workflow manually.
    • Cancel the old workflow context that is stuck.

 

Version history
Last update:
yesterday
Updated by:
Contributors