Lifecycle Event trigger script problem when using sys_id in variable in query

karoly_gersi
Giga Expert

Hello all,

 

Not sure if this is only an Activity Set trigger script-related issue only but here is what I experienced. I had to use a scripted condition for an Activity Set trigger, it checks a date and the completion of the previous Activity Set. The date part works, but the rest does not. Here is my script:

 

(function shouldActivitySetTrigger(parentCase, hrTriggerUtil) {
    var prerequisiteActivitySetId = '12345678912345678912345678912345';
    var parentCaseID = parentCase.sys_id.toString();

    var grActivitySets = new GlideRecord('sn_hr_le_activity_set_context');
    var query = 'hr_case.sys_id='+parentCaseID+'^activity_set.sys_id='+prerequisiteActivitySetId;
    grActivitySets.addEncodedQuery(query);
    grActivitySets.query();
    if (grActivitySets.next()) {
        if (grActivitySets.state !== 'finished') {
            return false;
        }
    }
    return true;  
})(parentCase, hrTriggerUtil);
 
I decided to check the context manually because the OOTB function offered via the hrTriggerUtil instance kept returning false even if the Activity Set has finished. But this approach does not work either (it does not find the record, getRowCount() shows 0 ), and it seems that the reason is somewhere around the parentCaseID variable. 
 
If this sys_id is hard-coded in the query, it works, even if the activity_set.sys_id is a variable. The "parentCase.sys_id" is originally of object type, but converting it to a string did not help either (I tried different methods, none of them worked).
 
I'm using addEncodedQuery() because addQuery() did not work in the first place. If I log the query, I can see it correctly (the same query I get when I query the table with the same values in the backend).
 
Does anyone have any idea why is this happening? (Keeping parentCase.sys_id in a variable is inevitable in this case.)
 
I found out that 'current' is also available in the script context but setting parentCaseID to current.sys_id did not work either, however, the value was the same.
 
Thanks for any hint that may help me solve this.
1 ACCEPTED SOLUTION

karoly_gersi
Giga Expert

Hi @Sandeep Rajput and @tejas1111 ,

 

Thank you for your valuable contribution to the issue!

 

However, it turned out that the problem is rooted in the operation of the ServiceNow system, one level higher than I expected. There was no problem with the query, with the variable and the ACLs, what happens is that  the query runs before the context record is created. It may be considered a ServiceNow bug since I basically did what is OOTB functionality (if you remember, the OOTB script that SN recommends did not work either). I could log the parentCaseID and it returned a valid ID because the parent case is already created when the trigger script runs but the context record does not exist yet (I used before query and before insert Business rules to log data and the sequence shows that the query is run before context record is created).

 

A possible workaround is to create a new Activity Set before the problematic one (which is not shown to the user on the portal) in which there is only a flow type task and the query is done from the subflow that's attached to it (in a do...while loop), then the original Activity Set only needs to wait for its completion. I tested it, it works fine.

 

Hope this will reach lots of fellow developers who ran into this issue.

 

View solution in original post

9 REPLIES 9

I see what’s happening here — your script is really close, but the issue comes down to how you’re handling the sys_id comparison inside the encoded query. In ServiceNow, the sys_id fields are always strings, but when you’re working in these trigger scripts, parentCase.sys_id isn’t just a plain string — it’s a GlideElement. Doing parentCase.sys_id.toString() doesn’t always evaluate the way you think inside the query. That’s why it works when you hard-code the value, but not when you reference the variable.

 

(function shouldActivitySetTrigger(parentCase, hrTriggerUtil) {
    var prerequisiteActivitySetId = '12345678912345678912345678912345';

    // getValue() ensures you’re actually working with the string value
    var parentCaseID = parentCase.getValue('sys_id');

    var grActivitySets = new GlideRecord('sn_hr_le_activity_set_context');
    grActivitySets.addQuery('hr_case', parentCaseID);
    grActivitySets.addQuery('activity_set', prerequisiteActivitySetId);
    grActivitySets.query();

    if (grActivitySets.next()) {
        if (grActivitySets.state != 'finished') {
            return false;
        }
    }
    return true;  
})(parentCase, hrTriggerUtil);

@karoly_gersi Can you check if you have the query_range and query_match ACLs configured correctly on table sn_hr_le_activity_set_context.

tejas1111
Tera Contributor

hi @karoly_gersi ,

I see what’s happening here — your script is really close, but the issue comes down to how you’re handling the sys_id comparison inside the encoded query. In ServiceNow, the sys_id fields are always strings, but when you’re working in these trigger scripts, parentCase.sys_id isn’t just a plain string — it’s a GlideElement. Doing parentCase.sys_id.toString() doesn’t always evaluate the way you think inside the query. That’s why it works when you hard-code the value, but not when you reference the variable.

 

(function shouldActivitySetTrigger(parentCase, hrTriggerUtil) {
    var prerequisiteActivitySetId = '12345678912345678912345678912345';

    // getValue() ensures you’re actually working with the string value
    var parentCaseID = parentCase.getValue('sys_id');

    var grActivitySets = new GlideRecord('sn_hr_le_activity_set_context');
    grActivitySets.addQuery('hr_case', parentCaseID);
    grActivitySets.addQuery('activity_set', prerequisiteActivitySetId);
    grActivitySets.query();

    if (grActivitySets.next()) {
        if (grActivitySets.state != 'finished') {
            return false;
        }
    }
    return true;  
})(parentCase, hrTriggerUtil);

 

tejas1111
Tera Contributor

 

In HR Activity Set trigger scripts, parentCase.sys_id is a GlideElement, not a raw string. When you concatenate or stringify it, you don’t always get the clean sys_id value that GlideRecord expects in a query. That’s why your hard-coded sys_id worked, but your variable one didn’t.

The fix is to use getValue('sys_id') (or parentCase.getUniqueValue()), which guarantees you’re passing the actual string value of the record’s sys_id. Your adjusted code is the right way to handle it:

(function shouldActivitySetTrigger(parentCase, hrTriggerUtil) {
    var prerequisiteActivitySetId = '12345678912345678912345678912345';

    // Get sys_id safely
    var parentCaseID = parentCase.getValue('sys_id'); 

    var grActivitySets = new GlideRecord('sn_hr_le_activity_set_context');
    grActivitySets.addQuery('hr_case', parentCaseID);
    grActivitySets.addQuery('activity_set', prerequisiteActivitySetId);
    grActivitySets.query();

    if (grActivitySets.next()) {
        if (grActivitySets.getValue('state') != 'finished') {
            return false;
        }
    }
    return true;
})(parentCase, hrTriggerUtil);

karoly_gersi
Giga Expert

Hi @Sandeep Rajput and @tejas1111 ,

 

Thank you for your valuable contribution to the issue!

 

However, it turned out that the problem is rooted in the operation of the ServiceNow system, one level higher than I expected. There was no problem with the query, with the variable and the ACLs, what happens is that  the query runs before the context record is created. It may be considered a ServiceNow bug since I basically did what is OOTB functionality (if you remember, the OOTB script that SN recommends did not work either). I could log the parentCaseID and it returned a valid ID because the parent case is already created when the trigger script runs but the context record does not exist yet (I used before query and before insert Business rules to log data and the sequence shows that the query is run before context record is created).

 

A possible workaround is to create a new Activity Set before the problematic one (which is not shown to the user on the portal) in which there is only a flow type task and the query is done from the subflow that's attached to it (in a do...while loop), then the original Activity Set only needs to wait for its completion. I tested it, it works fine.

 

Hope this will reach lots of fellow developers who ran into this issue.