ServiceNow business rule cheat sheet

Business rules run on the server when a record is displayed, inserted, updated, deleted or queried. current is the record being saved; previous is how it looked before the update.

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

(function executeRule(current, previous) { … })

#

The standard template. Keep your code inside the function so variables do not leak.

(function executeRule(current, previous /*null when async*/) {

    current.setValue('u_last_touched', new GlideDateTime().getValue());

})(current, previous);

When: before, after, async, display

#

Before: change current, it is saved anyway. After: update other records. Async: slow work in the background. Display: send data to the form with g_scratchpad.

(function executeRule(current, previous) {
    // Before rule: no update() needed, the change is saved with the record
    if (current.getValue('priority') == '1') {
        current.setValue('u_major_incident', true);
    }
})(current, previous);

current.field.changes() / changesTo(v) / changesFrom(v)

#

Checks whether a field changed in this update.

(function executeRule(current, previous) {
    if (current.state.changesTo(6)) {
        current.setValue('u_resolved_by', gs.getUserID());
    }
})(current, previous);

Often better as the rule condition, so the rule does not run at all otherwise.

previous.field

#

The value before this update, in before and after rules.

(function executeRule(current, previous) {
    if (previous.getValue('assigned_to') != current.getValue('assigned_to')) {
        gs.eventQueue('incident.reassigned', current);
    }
})(current, previous);

previous is not available in async rules.

current.setAbortAction(true)

#

Cancels the insert, update or delete. Use it in a before rule, with a message.

(function executeRule(current, previous) {
    if (gs.nil(current.getValue('close_notes'))) {
        gs.addErrorMessage('Add close notes before resolving.');
        current.setAbortAction(true);
    }
})(current, previous);

In after and async rules the record is already saved, so aborting does nothing.

current.operation() / current.isNewRecord()

#

operation() returns insert, update or delete; isNewRecord() is true while inserting.

(function executeRule(current, previous) {
    if (current.operation() == 'insert') {
        current.setValue('u_source', 'Self-service');
    }
})(current, previous);

g_scratchpad (display rule)

#

In a display business rule, put values on g_scratchpad; client scripts read them when the form loads.

(function executeRule(current, previous) {
    g_scratchpad.isVip = current.caller_id.vip.toString() == 'true';
})(current, previous);

Only display rules send g_scratchpad to the form.

current.update() in a business rule

#

Avoid: shown so you recognise it

Saves the record again inside its own save.

(function executeRule(current, previous) {
    current.setValue('state', 2);
    current.update();
})(current, previous);

In before rules the change is saved anyway; in after rules this re-runs every rule and can loop. Remove it.

Frequently asked questions

Should I use a before or an after business rule?

Use before to change or validate the record being saved; the change is stored with it, no update() needed. Use after to change other records or fire events once the save succeeded, and async for slow work such as integrations.