The fundamental mistake developers make with user lookups is not handling reference field null states properly. ServiceNow's reference fields can appear truthy when they're actually empty, causing runtime errors when you try to access getRefRecord() on a nil reference. This pattern encapsulates the safe lookup logic in a reusable utility that returns a predictable object structure, preventing the null reference exceptions that break production workflows.
When to use this pattern
- When you need user details in Business Rules, Script Includes, or Scheduled Jobs and have the
sys_idalready - When building notification logic that needs manager and department information for approval chains
- When processing user data from CSV imports or REST API calls where you need to enrich
sys_idvalues with readable information - When building utility functions for server-side user lookups that multiple scripts will call
When NOT to use this pattern
- Don't use this in client scripts — use GlideAjax to call the Script Include from the client instead
- Don't use this inside loops over large record sets — you'll create N+1 query problems. Use
addQuery()with an array ofsys_idvalues instead - Don't use this when you only need to check if a user exists — use
GlideRecord.isValidRecord()for existence checks - Don't use this for current user lookups in Business Rules — use
gs.getUser()which is cached and faster
Key behaviors and gotchas
- Reference fields can be truthy but nil — always use
nil()checks before callinggetRefRecord() getDisplayValue()handles reference fields automatically and returns readable names, notsys_idvalues- Domain separation affects user record visibility — this lookup respects the caller's domain scope
- User ACLs apply to this lookup — inactive users or users without read permissions return null
getUniqueValue()returns the canonicalsys_idstring, handling any GUID formatting inconsistencies- This pattern loads the full user record — if you only need one field, use direct dot-walking instead
Never assume manager or department fields are populated. Production user records frequently have empty reference fields, and calling getRefRecord() on a nil reference throws runtime exceptions that kill Business Rules and Break scheduled jobs.