Notifications

43 views

Symptoms


Any script in the instance could have unexpected behaviour.

Release


Any old, current or future release.

Cause


It is very common to see "gr" used as a variable name in scripts in a servicenow instance, in examples in the official documentation, community forums, and other places. e.g.

var gr = new GlideRecord('incident');

This is a bad idea!

The platform is Javascript and a lot of code is run in a global variable scope.

A "gr" defined in one business rule can clobber another "gr" defined in some other script, which happens to be running as part of the same update or transaction. One 'gr' can be replaced by the other 'gr' for something completely unrelated, and your script will continue running subsequent lines thinking it is the one it defined.

Your script could end up returning no query result, or updating a different record, from even a different table, than the one you have just queried for in your script. That can clearly have serious implications.

A real world example:

  • In a customer's incident, a simple gr.get(); query of the incident table from a script in a workflow returned no records returned because the Requested Item table was actually what was unknowingly being queried.
  • That was due to a requested item query business rule running, for a linked related record being run in the same transaction, that happened to also use 'gr' for the sc_req_item table.
  • The custom script in the workflow assumed a record was returned, but did not actually check. It used the gr.assigned_to value, which was null, and did not check it had a real value.
  • The 'null' result was then used for another query on the user table for a Notification, resulting in every employee in the company receiving the email.
  • Ouch!

In this kind of situation debugging to figure out what other code is breaking your code is also almost impossible, as you have to take everything running as part of the complete transaction into account. Adding lots of gs.info() messages into the code to double check all the values.

Resolution


General good javascript coding practice would avoid most of these issues.

You could wrap your scripts in a function to avoid your script clobbering another gr, which is why new business rules, calculated fields, etc. mostly now have a default script added to wrap the code to protect the variables within the function, but most scripts and including older business rules don't require this. Wrapping your code in a function is good coding practice, so always do this.

However wrapping your code in a function doesn't prevent another script from clobbering yours, so that is only reducing the chances of this happening. The best practice is to use your own unique variable names, relevant to the table you are using, and never use 'gr'. e.g. 

function updateOpenIncidents() {
    var openIncidentGr = new GlideRecord('incident');
    ....
}
updateOpenIncidents(); // runs the above function

So, just don't do it, and you will reduce the chances of this happening.

Additional Information


This doesn't just apply to "gr". Using "i" as a for loop counter everywhere is also bound to cause trouble sooner or later. Symptoms would be for loops that end early or go infinite.

Article Information

Last Updated:2018-11-23 03:12:41
Published:2018-11-23