top of page

Experiencing challenges with ServiceNow support?

Access professional, reliable assistance tailored to your needs—without breaking your budget.

ServiceNow Best Practice: Avoiding Hard-Coded Values in Scripts (Identification & Replacement)

ServiceNow strongly advises against using hard-coded values (such as fixed sys_id identifiers or names) in scripts, as they can lead to unpredictable results and maintenance headaches. A script that works in one instance may break in another if it relies on an ID or name that differs between environments. In fact, hard-coding sys_id values is explicitly discouraged by ServiceNow best practices. Instead, you should design your scripts to look up needed records dynamically – for example, by reference (using a unique name or code) or by retrieving values from a system property via gs.getProperty().


Use Case: Hard-coded sys_id values (the 32-character unique record identifiers in ServiceNow) are a common culprit. Suppose a business rule script directly uses a sys_id string to query a record. This will work until that sys_id changes (e.g. in another instance or after a data refresh), at which point the script will fail. Below, we’ll walk through how to identify such hard-coded values in your instance and then present solutions to replace them with more maintainable approaches.


Identifying Hard-Coded Values in Scripts

There are a couple of ways to find where hard-coded values (especially sys_ids) are used in your ServiceNow instance. We’ll cover two methods: using the built-in Instance Scan feature, and running a custom search script.


Using Instance Scan to Find Hard-Coded Patterns

ServiceNow’s Instance Scan feature allows creation of custom scan checks (e.g. a “Script Only” check) to detect patterns like hard-coded sys_ids in script fields.


The Instance Scan feature (under System Diagnostics) can automatically inspect your instance for code that violates best practices. You can configure a custom scan check to search for patterns that resemble a sys_id. For example, creating a Script Only Check that looks for any 32-character hexadecimal string (the format of a sys_id) can automatically flag scripts containing hard-coded sys_ids. This approach leverages the platform to scan across both client-side and server-side scripts. (There are different types of checks you can create — table, column, script, or linter — and in this case a script-based check is appropriate, as shown in the image above.) By running the instance scan with this custom check, you will get a report of all places in code where such patterns occur, highlighting potential hard-coded values.


Using a Script to Search for Hard-Coded sys_ids


Another approach is to run a background script that searches through script fields for the hard-coded value pattern. For example, the following Script Background code can scan any table for occurrences of a 32-character hex string (likely a sys_id) in its script content:

// Specify the table to scan (e.g., Business Rules table)
var tableName = "sys_script";
identifyHardCode(tableName);

function identifyHardCode(tableName) {
    // Regex for 32 hex characters (potential sys_id)
    var regexp = /[0-9a-f]{32}/;
    var gr = new GlideRecord(tableName);
    gr.query();
    while (gr.next()) {
        var scriptText = gr.script.toString();
        if (scriptText.match(regexp)) {
            gs.print('Sys_id found in script: ' + gr.name);
        }
    }
}

In the script above, we define a function that queries all records of a given table (for example, Business Rule records in the sys_script table). It uses a regular expression to detect any 32-character hexadecimal sequence in each record’s script field. If a match is found, it prints out the name of that script. You can call identifyHardCode() for different tables (e.g. client scripts, UI actions, etc.) by changing the tableName variable or extending the script to scan multiple tables.


After running this scan script (for instance, on the Business Rules table), the output will list all scripts that contain a hard-coded sys_id:

Output of the scan script, showing several business rule scripts where a sys_id was found. Each line indicates a script (by name) that contains a hard-coded sys_id value.


From the sample output above, you can see multiple script names flagged with “Sys_id found in script…”. These are candidates for cleanup – we now know where hard-coded references exist and can proceed to fix them.


Replacing Hard-Coded Values with Maintainable Solutions


Identifying hard-coded values is only half the battle. The next step is to replace those static references with more flexible solutions. ServiceNow recommends two primary strategies to avoid hard-coding:


  1. Lookup by Reference: Whenever possible, query or reference records by a natural key (like a unique name or another attribute) instead of embedding the sys_id. This often means using reference fields or GlideRecord queries that search by a field value rather than get(sys_id). For example, if a script was using a group’s sys_id, you might instead query by the group’s name or some code. (Be cautious with this approach, as names can change due to organization updates – using dynamic data still requires maintenance if the reference field value changes. In many cases, combining this with the property approach below is ideal.)

  2. Use System Properties: Externalize the value (such as a sys_id or other constant) into a system property, and retrieve it in the script via gs.getProperty(). This way, if the value needs to change, you update the property value rather than editing script logic. This approach is especially useful for environment-specific IDs or configuration values.

We’ll focus on the system properties solution, since it’s a robust method supported by ServiceNow’s best practices and works for both server and client scripts (with a slight variation).


Server-Side Solution: System Properties and gs.getProperty()


On the server side (business rules, script includes, etc.), using a system property is straightforward. First, define a new property in System Properties (e.g. create a property named company.default.group and set its value to the desired sys_id or name of a record). Then, in your script, replace the hard-coded value with a call to gs.getProperty('<property_name>').


For example, suppose a business rule originally contained:

// Hard-coded query (not recommended)
gr.get('93ee0b121b1dd9900b8a9979b04bcb88');  // some sys_id

We can refactor this by storing that sys_id in a property (say, x_acme.default.record.sys_id) and then doing:

// Recommended approach using system property
gr.get(gs.getProperty('x_acme.default.record.sys_id'));

This way, the actual ID is abstracted away. If the record’s sys_id changes or we move to another instance, we only need to update the property – the script itself remains unchanged. The difference is clear: in the first case the sys_id is hard-coded in the script, whereas in the second case the script dynamically pulls the correct ID from a property at runtime.


ServiceNow’s Scripting Technical Best Practices documentation also endorses this approach, noting that using gs.getProperty() to retrieve configurable values is a best practice. By avoiding direct constants, our code adapts to changes with minimal effort.


Client-Side Solution: GlideAjax for Property Lookup


In client-side scripts (e.g. client scripts or catalog client scripts), we cannot use gs.getProperty() directly because GlideSystem methods are server-side only. However, we can still leverage system properties by using a GlideAjax call to get the property value from the server:


  • Create a Script Include (AJAX Processor): Write a server-side Script Include that extends AbstractAjaxProcessor. This script include will have a function (accessible via GlideAjax) which reads the property and returns its value. For example, a script include AJAXGetProperty might have a function getValue(name) that does return gs.getProperty(name) for a given property name. Make sure to mark the script include as Client callable so that client scripts can invoke it.

  • Call it from the Client Script: In your client script, use the GlideAjax class to call the above script include. For instance, you can do:


  • In the snippet above, the client script calls the GlideAjax processor AJAXGetProperty, asking it to execute the getValue function with a parameter (the property name we want). When the response comes back, sysIdValue will contain the actual sys_id from the property, which we can then use on the client (for example, setting a reference field value or triggering some client-side logic with that ID).

Using this two-part method (Script Include + GlideAjax), the client-side code gets dynamic data from the server without any hard-coded values. This pattern is commonly used to fetch any server data in client scripts, and here we apply it to retrieve system property values.


Conclusion


By identifying and eliminating hard-coded values in your ServiceNow scripts, you make your applications more robust and easier to maintain. The Instance Scan tool or a custom script can help you find all those hidden “magic numbers” (such as sys_ids) in your code. Once found, you should replace them either by looking up records through reference fields or by storing those values in system properties and pulling them dynamically at runtime.


These best practices ensure that your code adapts to changes in data and across different instances. For example, if an administrator needs to swap out a group or update a record ID, they can do so in one place (a property or a reference record) rather than hunting through scripts. This significantly reduces the chance of errors when moving from development to production or upgrading to a new release.


Following ServiceNow’s guidance on avoiding hard-coded values will lead to more reliable and secure scripts. Always prefer configuration over hard-coding: what’s in a property or data table today might save you from a broken script tomorrow.

Experiencing challenges with ServiceNow support?

Access professional, reliable assistance tailored to your needs—without breaking your budget.

CONTACT

New Zealand HQ

Integrated Knowledge Consulting Office

Level 3, 93 Grafton Road

Auckland

South Korea

Integrated Knowledge Consulting Office

BMY역삼타워 6층

서울특별시 강남구 역삼동 678-10번지

 

info@ikconsulting.com

Thanks for submitting!

  • LinkedIn Social Icon

© Copyright 2025 Integrated Knowledge Consulting. All rights reserved.

bottom of page