The setAbortAction() method prevents a database transaction from committing, but it only works in Before Business Rules — not After, not async rules, not anywhere else. Most developers discover this limitation the hard way after writing validation logic in the wrong rule type. The platform executes After rules post-transaction, so by then it's too late to abort. Pair setAbortAction(true) with gs.addErrorMessage() to show the user exactly why their save failed — otherwise they'll just see a generic error or the form will silently fail to save.
When to use this
- Enforcing business rules that must prevent bad data from entering the database — invalid state transitions, required field combinations, or referential integrity checks
- Server-side validation that can't be bypassed by direct database operations, imports, or web service calls
- Complex validation requiring GlideRecord queries against related tables that would be impossible in
g_form.addErrorMessage() - Validation that must run on both form saves and programmatic updates via GlideRecord
When NOT to use this
- Client-side validation that should happen before the user submits — use
g_form.addErrorMessage()in onChange or onSubmit client scripts instead - After Business Rules —
setAbortAction()is silently ignored because the transaction already committed - Async Business Rules — use Before rules for validation, Async rules only for side effects like notifications
- Simple field validation that Data Policies can handle — let the platform enforce it declaratively
Key behaviors and gotchas
setAbortAction()only works in Before rules — the method exists elsewhere but does nothing- Error messages disappear on form refresh — use
gs.addInfoMessage()instead if you need persistence across page loads - Business Rule order matters — if multiple Before rules call
setAbortAction(), later rules still execute but can't un-abort the transaction - State field values are integers as strings: '1', '2', '6' — never compare with integers or the comparison fails silently
- Use
setLimit(1)when you only need to check existence — prevents unnecessary full table scans in validation logic - Always use
returnaftersetAbortAction()to prevent further validation logic from running unnecessarily
Never call setAbortAction() inside a loop over multiple GlideRecords — it only aborts the current record's transaction, not the entire loop. Each record in your loop will still attempt to save individually.
Enjoying this? Get one deep-dive per week.
Join 1,000+ ServiceNow pros — scripts, GlideRecord patterns, Flow Designer techniques, and career moves. Free.