gliderecord-patterns
This skill should be used when the user asks to "query records", "GlideRecord", "database query", "get records", "update records", "insert record", "delete record", or any ServiceNow database operations.
Best use case
gliderecord-patterns is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
This skill should be used when the user asks to "query records", "GlideRecord", "database query", "get records", "update records", "insert record", "delete record", or any ServiceNow database operations.
Teams using gliderecord-patterns should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/gliderecord-patterns/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How gliderecord-patterns Compares
| Feature / Agent | gliderecord-patterns | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
This skill should be used when the user asks to "query records", "GlideRecord", "database query", "get records", "update records", "insert record", "delete record", or any ServiceNow database operations.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# GlideRecord Best Practices for ServiceNow
GlideRecord is the primary API for database operations in ServiceNow. Following these patterns ensures efficient and secure queries.
## Basic Query Patterns
### Get Single Record by sys_id
```javascript
var gr = new GlideRecord("incident")
if (gr.get("sys_id_here")) {
gs.info("Found: " + gr.getValue("number"))
}
```
### Get Single Record by Field
```javascript
var gr = new GlideRecord("sys_user")
if (gr.get("user_name", "admin")) {
gs.info("Found user: " + gr.getValue("name"))
}
```
### Query Multiple Records
```javascript
var gr = new GlideRecord("incident")
gr.addQuery("active", true)
gr.addQuery("priority", "1")
gr.orderByDesc("sys_created_on")
gr.setLimit(100)
gr.query()
while (gr.next()) {
gs.info(gr.getValue("number"))
}
```
## Encoded Queries (Faster)
Use encoded queries for complex conditions - they're more efficient than multiple addQuery calls:
```javascript
var gr = new GlideRecord("incident")
// Encoded query from list view URL or Query Builder
gr.addEncodedQuery("active=true^priority=1^assigned_toISEMPTY")
gr.query()
while (gr.next()) {
// Process records
}
```
## Performance Tips
### 1. Always Use setLimit()
```javascript
// When you only need X records
var gr = new GlideRecord("incident")
gr.addQuery("active", true)
gr.setLimit(10) // Don't fetch more than needed
gr.query()
```
### 2. Use getValue() for Strings
```javascript
// CORRECT - Returns string value
var number = gr.getValue("number")
// ALSO WORKS but returns GlideElement
var element = gr.number
var numberStr = gr.number.toString()
```
### 3. Use getDisplayValue() for References
```javascript
// Get the display value of a reference field
var assignedToName = gr.getDisplayValue("assigned_to")
// Get the sys_id of a reference field
var assignedToId = gr.getValue("assigned_to")
```
### 4. Avoid Queries in Loops
```javascript
// BAD - Query inside loop
for (var i = 0; i < userIds.length; i++) {
var gr = new GlideRecord("sys_user")
gr.get(userIds[i]) // N queries!
}
// GOOD - Single query with IN clause
var gr = new GlideRecord("sys_user")
gr.addQuery("sys_id", "IN", userIds.join(","))
gr.query()
while (gr.next()) {
// Process all users at once
}
```
### 5. Use GlideAggregate for Counts
```javascript
// BAD - Counting with GlideRecord
var count = 0
var gr = new GlideRecord("incident")
gr.addQuery("active", true)
gr.query()
while (gr.next()) {
count++
}
// GOOD - Use GlideAggregate
var ga = new GlideAggregate("incident")
ga.addQuery("active", true)
ga.addAggregate("COUNT")
ga.query()
if (ga.next()) {
var count = ga.getAggregate("COUNT")
}
```
## CRUD Operations
### Insert
```javascript
var gr = new GlideRecord("incident")
gr.initialize()
gr.setValue("short_description", "New incident")
gr.setValue("caller_id", gs.getUserID())
gr.setValue("priority", "3")
var sysId = gr.insert()
```
### Update
```javascript
var gr = new GlideRecord("incident")
if (gr.get("sys_id_here")) {
gr.setValue("state", "6") // Resolved
gr.setValue("close_notes", "Issue fixed")
gr.update()
}
```
### Delete (Use with Caution!)
```javascript
var gr = new GlideRecord("incident")
if (gr.get("sys_id_here")) {
gr.deleteRecord()
}
```
### Bulk Update
```javascript
var gr = new GlideRecord("incident")
gr.addQuery("state", "6") // Resolved
gr.addQuery("resolved_at", "<", gs.daysAgoStart(30))
gr.query()
while (gr.next()) {
gr.setValue("state", "7") // Closed
gr.update()
}
```
## Query Operators
| Operator | Example | Description |
| ------------ | ------------------------------------------------------ | --------------------- |
| `=` | `addQuery('active', true)` | Equals |
| `!=` | `addQuery('active', '!=', true)` | Not equals |
| `>`, `<` | `addQuery('priority', '<', '3')` | Greater/Less than |
| `>=`, `<=` | `addQuery('sys_created_on', '>=', gs.daysAgoStart(7))` | Greater/Less or equal |
| `CONTAINS` | `addQuery('short_description', 'CONTAINS', 'error')` | Contains string |
| `STARTSWITH` | `addQuery('number', 'STARTSWITH', 'INC')` | Starts with |
| `ENDSWITH` | `addQuery('email', 'ENDSWITH', '@company.com')` | Ends with |
| `IN` | `addQuery('state', 'IN', '1,2,3')` | In list |
| `NOT IN` | `addQuery('state', 'NOT IN', '6,7')` | Not in list |
| `ISEMPTY` | `addQuery('assigned_to', 'ISEMPTY', '')` | Field is empty |
| `ISNOTEMPTY` | `addQuery('assigned_to', 'ISNOTEMPTY', '')` | Field is not empty |
## Security Considerations
1. **setWorkflow(false)** - Skip business rules for bulk operations
2. **setLimit()** - Prevent runaway queries
3. **Check canRead()/canWrite()** - Verify ACL permissions
4. **Never trust user input** - Validate before using in queriesRelated Skills
projection-patterns
Build read models and projections from event streams. Use when implementing CQRS read sides, building materialized views, or optimizing query performance in event-sourced systems.
GitOps Patterns
ArgoCD ApplicationSets, progressive delivery, Harness GitX, and multi-cluster GitOps patterns
aria-patterns
Provides ARIA roles, states, and properties for interactive components. Use when building custom widgets, fixing screen reader issues, or implementing modals, tabs, accordions, menus, or dialogs accessibly.
analyze-patterns
Use this skill when you need to analyze code for design patterns, anti-patterns, naming conventions, and code duplication. This skill excels at identifying architectural patterns, detecting code smells, and ensuring consistency across the codebase.
acc-stability-patterns-knowledge
Stability Patterns knowledge base. Provides patterns, antipatterns, and PHP-specific guidelines for Circuit Breaker, Retry, Rate Limiter, Bulkhead, and resilience audits.
a2a-patterns
Agent-to-Agent (A2A) protocol implementation patterns for Google ADK - exposing agents via A2A, consuming external agents, multi-agent communication, and protocol configuration. Use when building multi-agent systems, implementing A2A protocol, exposing agents as services, consuming remote agents, configuring agent cards, or when user mentions A2A, agent-to-agent, multi-agent collaboration, remote agents, or agent orchestration.
wcag-audit-patterns
Conduct WCAG 2.2 accessibility audits with automated testing, manual verification, and remediation guidance. Use when auditing websites for accessibility, fixing WCAG violations, or implementing ac...
testing-patterns
Testing patterns using bun:test with in-memory SQLite. Use when writing unit tests, integration tests, or router tests.
midnight-dapp:testing-patterns
Use when writing unit tests for Midnight contract interaction code, integration testing without ZK proofs, E2E testing with Playwright or Cypress, or setting up CI/CD pipelines for Midnight DApps.
e2e-testing-patterns
Master end-to-end testing with Playwright and Cypress to build reliable test suites that catch bugs, improve confidence, and enable fast deployment. Use when implementing E2E tests, debugging flaky tests, or establishing testing standards.
code-review-patterns
Internal skill. Use cc10x-router for all development tasks.
auth-implementation-patterns
Master authentication and authorization patterns including JWT, OAuth2, session management, and RBAC to build secure, scalable access control systems. Use when implementing auth systems, securing A...