ServiceNow GlideRecord cheat sheet

GlideRecord reads and writes records on the server. Build the query, run it, then loop over the results. It ignores ACLs, so use GlideRecordSecure when the data goes back to a user.

Server27 methods · examples checked with the Script Checker · reviewed October 2026

new GlideRecord('table')

#

Creates a GlideRecord for a table. Nothing is read until you call query() or get().

var inc = new GlideRecord('incident');
inc.addActiveQuery();
inc.query();
while (inc.next()) {
    gs.info(inc.getValue('number'));
}

addQuery(field, value)

#

Adds a condition: the field equals the value. Several addQuery() calls are joined with AND.

var inc = new GlideRecord('incident');
inc.addQuery('priority', 1);
inc.addQuery('state', '!=', 7);
inc.query();

addQuery(field, operator, value)

#

Adds a condition with an operator: =, !=, >, >=, <, <=, IN, NOT IN, STARTSWITH, ENDSWITH, CONTAINS, DOES NOT CONTAIN, INSTANCEOF.

var inc = new GlideRecord('incident');
inc.addQuery('short_description', 'CONTAINS', 'vpn');
inc.addQuery('priority', 'IN', '1,2');
inc.addQuery('sys_created_on', '>=', gs.daysAgoStart(7));
inc.query();

Operators are uppercase. IN takes a comma-separated string or an array.

addOrCondition(field, operator, value)

#

Adds an OR to a condition. Call it on the object that addQuery() returns.

var inc = new GlideRecord('incident');
var cond = inc.addQuery('priority', 1);
cond.addOrCondition('priority', 2);
inc.addActiveQuery();
inc.query();

This reads as (priority is 1 OR 2) AND active.

addEncodedQuery(query)

#

Adds conditions written as an encoded query, exactly as copied from a list filter.

var inc = new GlideRecord('incident');
inc.addEncodedQuery('active=true^priorityIN1,2^assigned_toISEMPTY');
inc.query();

Build the filter in a list, right-click the breadcrumb and choose Copy query. Field names it does not recognise are ignored silently.

addActiveQuery()

#

Shortcut for addQuery("active", true).

var task = new GlideRecord('task');
task.addActiveQuery();
task.query();

addNullQuery(field) / addNotNullQuery(field)

#

Matches records where the field is empty, or is not empty.

var inc = new GlideRecord('incident');
inc.addActiveQuery();
inc.addNullQuery('assigned_to');
inc.query();

orderBy(field) / orderByDesc(field)

#

Sorts the results, ascending or descending.

var inc = new GlideRecord('incident');
inc.addActiveQuery();
inc.orderByDesc('sys_created_on');
inc.setLimit(10);
inc.query();

setLimit(n)

#

Returns at most n records. Use setLimit(1) when you only need to know whether one exists.

var dup = new GlideRecord('incident');
dup.addQuery('correlation_id', correlationId);
dup.setLimit(1);
dup.query();
var exists = dup.hasNext();

query() and next()

#

query() runs the query; next() moves to the next record and returns false when there are no more.

var inc = new GlideRecord('incident');
inc.addActiveQuery();
inc.query();
while (inc.next()) {
    gs.info(inc.getValue('number'));
}

If the table has a field called next, use _query() and _next() instead.

hasNext()

#

Returns true when there is at least one more record, without moving to it.

var gr = new GlideRecord('sys_user_group');
gr.addQuery('name', 'Service Desk');
gr.setLimit(1);
gr.query();
if (gr.hasNext()) {
    gs.info('Group exists');
}

get(sysId) / get(field, value)

#

Loads one record by sys_id, or by any field. Returns true if a record was found.

var user = new GlideRecord('sys_user');
if (user.get('user_name', 'abel.tuter')) {
    gs.info(user.getValue('email'));
}

Always check the return value; on false the object is empty.

getValue(field)

#

Returns the stored value of a field as a string (a sys_id for reference fields), or null when empty.

var inc = new GlideRecord('incident');
if (inc.get(incidentId)) {
    var callerId = inc.getValue('caller_id');
    var state = inc.getValue('state');
}

Prefer getValue() over inc.field: the dot form returns a GlideElement object, not a string.

getDisplayValue(field)

#

Returns what a user sees for a field: the label of a choice, the name of a referenced record.

var inc = new GlideRecord('incident');
if (inc.get(incidentId)) {
    gs.info(inc.getDisplayValue('state'));      // "In Progress"
    gs.info(inc.getDisplayValue('caller_id'));  // "Abel Tuter"
}

setValue(field, value)

#

Sets a field value. For reference fields, pass the sys_id.

var inc = new GlideRecord('incident');
if (inc.get(incidentId)) {
    inc.setValue('state', 2);
    inc.setValue('assigned_to', userId);
    inc.update();
}

getUniqueValue()

#

Returns the sys_id of the current record.

var inc = new GlideRecord('incident');
inc.initialize();
inc.setValue('short_description', 'Printer offline');
inc.insert();
gs.info(inc.getUniqueValue());

initialize() and insert()

#

initialize() prepares a new record with default values; insert() saves it and returns its sys_id.

var inc = new GlideRecord('incident');
inc.initialize();
inc.setValue('short_description', 'Printer on floor 3 is offline');
inc.setValue('caller_id', gs.getUserID());
var incidentId = inc.insert();

Without initialize() (or newRecord()), field defaults are not applied.

update()

#

Saves changes to an existing record and runs business rules.

var inc = new GlideRecord('incident');
if (inc.get(incidentId)) {
    inc.setValue('work_notes', 'Escalated to the network team');
    inc.update();
}

Do not call current.update() in a business rule; set the fields in a before rule instead.

deleteRecord()

#

Deletes the current record.

var att = new GlideRecord('sys_attachment');
if (att.get(attachmentId)) {
    att.deleteRecord();
}

updateMultiple() / deleteMultiple()

#

Applies the same change to, or deletes, every record matching the query, without looping.

var logs = new GlideRecord('u_integration_log');
logs.addQuery('sys_created_on', '<', gs.daysAgoStart(90));
logs.deleteMultiple();

Always add conditions first. Without any, every record in the table is changed or deleted.

getEncodedQuery()

#

Returns the query built so far as an encoded query string. Handy for logging and debugging.

var inc = new GlideRecord('incident');
inc.addActiveQuery();
inc.addQuery('priority', 1);
gs.info(inc.getEncodedQuery()); // active=true^priority=1

isValidField(field) / isValid()

#

isValidField() checks that a field exists on the table; isValid() checks that the table exists.

var gr = new GlideRecord('incident');
if (gr.isValidField('u_vendor')) {
    gr.addQuery('u_vendor', vendorId);
}

setWorkflow(false)

#

Skips business rules, notifications, workflows and audit for the next update.

var inc = new GlideRecord('incident');
if (inc.get(incidentId)) {
    inc.setWorkflow(false); // data fix: skip notifications on purpose
    inc.setValue('u_migrated', true);
    inc.update();
}

Use it only when skipping all of that is intended, such as data fixes.

autoSysFields(false)

#

Updates the record without changing Updated, Updated by and the update count.

var inc = new GlideRecord('incident');
if (inc.get(incidentId)) {
    inc.autoSysFields(false); // data fix: keep the original updated date
    inc.setValue('u_migrated', true);
    inc.update();
}

canRead() / canWrite() / canCreate() / canDelete()

#

Checks the ACLs for the logged-in user on the current record.

var inc = new GlideRecord('incident');
if (inc.get(incidentId) && inc.canRead()) {
    gs.info(inc.getValue('short_description'));
}

new GlideRecordSecure('table')

#

Same API as GlideRecord, but enforces ACLs: records and fields the user cannot read are left out.

var inc = new GlideRecordSecure('incident');
inc.addQuery('caller_id', gs.getUserID());
inc.query();
while (inc.next()) {
    gs.info(inc.getValue('number'));
}

Use it in client-callable script includes and scripted REST APIs.

getRowCount()

#

Avoid: shown so you recognise it

Returns the number of records the query returned.

var inc = new GlideRecord('incident');
inc.addActiveQuery();
inc.query();
var count = inc.getRowCount();

It loads every matching record just to count them. Use GlideAggregate with COUNT instead.

Frequently asked questions

What is the difference between getValue() and dot-walking a field?

gr.getValue('state') returns the value as a string. gr.state returns a GlideElement object, which behaves like a string in most places but breaks strict comparisons (===) and stores a reference when pushed into an array inside a loop.

When should I use GlideRecordSecure instead of GlideRecord?

Whenever the records go back to a user: client-callable script includes (GlideAjax), scripted REST APIs and widgets. GlideRecordSecure applies ACLs; GlideRecord does not.

Why does my GlideRecord query return every record?

ServiceNow ignores conditions on field names it does not recognise, so a typo such as prority matches everything. Check the field name, or set the system property glide.invalid_query.returns_no_rows to true.