← ClaudeAtlas

sn-scriptinglisted

Use BEFORE writing any ServiceNow server/client script (GlideRecord, Script Includes, Business Rules, .server.js/.client.js, Jelly UI Pages) — required by the authoring gate. Documents the scoped-API allow-list, silent-failure patterns, and Jelly escape rules.
theogyeezy/skillz · ★ 0 · API & Backend · score 67
Install: claude install-skill theogyeezy/skillz
# ServiceNow Scoped Scripting Scoped applications run in a FENCED execution context. ServiceNow wraps global objects in scoped wrappers that only expose an allow-listed subset. Code that works in global scope throws `Cannot find function <method> in object` at runtime in scope — and the SDK build/TypeScript check does NOT catch any of it, because fencing is enforced by the instance at runtime. General JavaScript intuition is not allowed here; these rules were each paid for with a broken build or a 5-minute transaction timeout. ## GlideRecord access (the most-violated rule) Use EXCLUSIVELY: - `gr.getValue('field')` — raw value / reference sys_id - `gr.getDisplayValue('field')` — display label (including reference labels) - `gr.getUniqueValue()` — the record's own sys_id NEVER: dot-notation reads (`gr.field`), method chaining (`gr.ref_field.getDisplayValue()`), bracket access (`gr[name]`). Scoped proxies return `undefined` SILENTLY — no error, just wrong data downstream. **Exception — journal fields flip the rule:** `gr.setValue('work_notes', text)` / `gr.setValue('comments', text)` creates ZERO `sys_journal_field` rows from server-side scripts even though `update()` returns success. When the audit trail matters, journal fields use dot ASSIGNMENT: `gr.work_notes = text;`. Never build GlideRecord queries by string-concatenating user input (injection). Use `addQuery(field, op, value)` parameters or `GlideRecordSecure`. ## ScopedUser API | Works in scope | Does NOT exist i