Discussion: Why is this OOB Client Script using GlideRecord?

Ajay_saitej
Tera Contributor

 

For years, the ServiceNow developer community and official training modules have hammered home a golden rule: Avoid using GlideRecord in Client Scripts. We are taught to use GlideAjax with asynchronous XMLHttpRequests to keep the browser responsive and follow best practices.

 

However, while digging through some OOB configurations after Zurich upgrade, I stumbled upon a KB article -https://support.servicenow.com/kb?id=kb_article_view&sysparm_article=KB2676169  and when I checked I found that client Script that seems to ignore the "Standard" playbook.

 

Below is an OOB Client Script snippet that performs a lookup on the sys_user_grmember table:

JavaScript
 
function onChange(control, oldValue, newValue, isLoading, isTemplate) {
    if (isLoading)
        return;

    if (oldValue != newValue)
        g_scratchpad.formValue = newValue;

    if (newValue === '' || newValue == null || oldValue != newValue || newValue != g_scratchpad.formValue) {
        if (newValue && g_form.getValue("assigned_to")) {
            // Found: Client-side GlideRecord query
            var groupLookupGr = new GlideRecord('sys_user_grmember');
            groupLookupGr.addQuery('group', newValue);
            groupLookupGr.addQuery('user', g_form.getValue("assigned_to"));
            groupLookupGr.setLimit(1);
            groupLookupGr.query(groupLookupCallback); 
        } else {
            g_form.setValue("assigned_to", "");
        }
    }
}

function groupLookupCallback(groupLookupGr) {
    if (!groupLookupGr.hasNext())
        g_form.setValue("assigned_to", "");
}
  1. Client-Side GlideRecord: While it uses a callback function (making it asynchronous), the official recommendation has long shifted toward GlideAjax for better security control and performance optimization.

  2. Maintenance: If a junior developer sees this, they might assume GlideRecord on the client side is the preferred way to query data.

  3. We often see these scripts flagged during ACE (Automated Checking Entity) reports or HealthScans, yet they persist in the core platform.

Discussion Points

  • Is it time to relax the "No GlideRecord on Client" rule if a callback is used?

  • Or should ServiceNow prioritize refactoring these legacy OOB scripts to meet current 2026 standards?

  • Does the simplicity of this approach outweigh the overhead of setting up a Script Include for a simple 1-line check?

I’d love to hear the thoughts of the experts and the product teams on why this pattern remains the standard for some OOB features


@Earl Duque @laurenmcman @Travis Toulson @Tim Woodruff @Mark Roethof 
#ServiceNow #BestPractices #ClientScript #Scripting #GlideRecord #Development

6 REPLIES 6

Tanushree Maiti
Mega Patron

Hi @Ajay_saitej ,

 

I’ve noticed the same thing before — there are several places where ServiceNow’s OOB scripts don’t fully align with their own recommended best practices. I assume ServiceNow is gradually addressing these issues, but there are probably many dependencies involved.

 

For example, ServiceNow recommends avoiding GlideRecord queries inside ACLs, yet there are still a few OOB ACL scripts where GlideRecord is being used.

Please mark this response as Helpful & Accept it as solution if it assisted you with your question.
Regards
Tanushree Maiti
ServiceNow Technical Architect
Linkedin:

Vikram Reddy
Giga Guru

This is a good catch, but I would not read this OOB script as permission to relax the rule.

 

The important distinction is that the callback makes the client-side GlideRecord asynchronous, so it avoids the worst browser-freezing behavior. But the “avoid GlideRecord in Client Scripts” guidance is broader than sync vs async. It is also about controlling what logic runs on the server, limiting returned data, keeping business rules reusable, supporting scoped apps, and avoiding client scripts that directly query arbitrary tables.

For this exact OOB case, the blast radius is small: it queries sys_user_grmember, uses two indexed-looking constraints, sets setLimit(1), and only checks existence. So it is probably a pragmatic legacy/platform-owned implementation, not a pattern ServiceNow wants every customer developer to copy.

 

My take:

  • Do not relax the standard. Async client GlideRecord is less harmful than sync client GlideRecord, but GlideAjax is still the better custom-development pattern.
  • OOB code is not always best-practice teaching material. Some OOB scripts remain for backward compatibility, classic UI behavior, upgrade safety, or historical reasons.
  • GlideAjax is not automatically “more secure.” A poorly written client-callable Script Include can bypass ACL expectations. But a well-written one lets you validate inputs and return only a boolean like true/false, which is cleaner than exposing record queries to the browser.

Actually, that’s the most frustrating part: this isn’t legacy code. This is a new Client Script introduced in the Zurich release (2026) on sctask table.

If this were an old script from New York or Orlando, I could understand the 'backward compatibility' argument. But since this was authored for the latest platform version, it feels like a deliberate choice by the internal dev team to ignore the GlideAjax standard.

Most automated governance tools (like ServiceNow's own Instance Scan) will flag GlideRecord on the client. It creates a confusing double standard when the platform's own code would fail its own best-practice scanner. 😞

I agree with your main point though: if ServiceNow ships new OOB client scripts that use client GlideRecord, the platform should either:

  • refactor them to GlideAjax,
  • document why the exception is acceptable, or
  • make governance tools distinguish OOB platform exceptions from customer-authored code.

Otherwise developers are left with a double standard: official guidance says “avoid this,” but fresh OOB code appears to model it.