The relationship between sc_request and sc_req_item is straightforward, but catalog variables live in a third table most developers miss: sc_item_option_mtom. This many-to-many relationship stores the actual variable values that users submitted, and you need to join through sc_item_option to get variable metadata. The pattern above handles both the RITM enumeration and variable extraction in a single pass, avoiding the N+1 query trap that kills performance when you have requests with dozens of items.

When to use this pattern

  • Processing approval workflows that need to act on individual RITMs within a request
  • Business rules on sc_request that need to validate or modify child items before completion
  • Scheduled jobs that process batches of requests and need RITM-level detail for reporting or integration
  • Fix scripts that need to bulk-update RITMs based on parent request criteria

When NOT to use this pattern

  • Client-side scripts — use GlideAjax to call a Script Include that implements this pattern
  • When you only need RITM counts or aggregates — use GlideAggregate with addAggregate('COUNT')
  • Inside loops over other GlideRecord results — you'll create a query storm that times out on large datasets
  • Processing requests with 50+ RITMs in synchronous business rules — use events or scheduled processing instead

Key behaviors and gotchas

  • RITM state values are integers: 1=Open, 2=Work in Progress, 3=Closed Complete, 4=Closed Incomplete, 7=Closed Skipped
  • Catalog variables require joining through sc_item_option_mtom — they're not fields on sc_req_item
  • Variable values are always strings, even for numeric and boolean catalog variables
  • RITMs inherit ACLs from their catalog items — not all RITMs in a request may be visible to the current user
  • Multi-row variable sets create multiple sc_item_option_mtom records per RITM — group by row_index if needed
  • The request field on sc_req_item is indexed — queries by request are fast even with thousands of RITMs
⚠️

Never use dot-notation like current.ritems to navigate from request to RITMs — it returns a GlideElement, not a GlideRecord, and you can't iterate or query it. Always query sc_req_item explicitly with the request sys_id.

Free Newsletter

Enjoying this? Get one deep-dive per week.

Join 1,000+ ServiceNow pros — scripts, GlideRecord patterns, Flow Designer techniques, and career moves. Free.

No spam · Unsubscribe anytime