sn-scriptinglisted
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