debugging-techniques
Skill41 starsChanged 6 days agoApache-2.0View on GitHub
Comprehensive guide to debugging ServiceNow server-side and client-side code
We split this skill into the rules it gives an agent
19 rules. About 0 are common, 15 are distinctive, and 4 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈15
Distinctive · estimate
This author's own choices. Worth a look.
4
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 167
Use Watch panel to monitor variables
- Distinctive: line 168
Use Scope panel to inspect local/closure variables
- Distinctive: line 191
Look for calls to:
- Distinctive: line 358
Check ACL logs: System Logs > Security
- Distinctive: line 373
Check System Logs for stack trace
- Distinctive: line 374
Use Script Debugger to step through
- Distinctive: line 381
Add GlideAggregate for counting instead of looping
- Distinctive: line 382
Use setLimit() to restrict result sets
- Distinctive: line 389
Check for recursive business rules
- Distinctive: line 390
Add condition to prevent re-entry:
- Distinctive: line 401
Use GlideAggregate for counts
- Distinctive: line 433
Clean up debug code: Remove or disable verbose logging before promoting to production
- Very specific: line 435
Structured logging: Use consistent format: [Component] Action - Details
- Distinctive: line 436
Test in sub-production: Always debug in dev/test before touching production
- Very specific: line 445
Check System Properties for glide.log.level
- Very specific: line 446
Ensure glide.script.log.level allows your log level
- Very specific: line 447
Use gs.error() which always logs
- Distinctive: line 454
Ensure debugging enabled for YOUR session (not another admin)
- Distinctive: line 456
Verify script condition evaluates to true
≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
ServiceNow Debugging Techniques
Overview
Master the art of debugging ServiceNow applications using built-in tools and techniques. This skill covers server-side debugging, client-side debugging, log analysis, and common error resolution.
- What problem does it solve? Identifies and resolves issues in business rules, script includes, client scripts, workflows, and flows
- Who should use this skill? ServiceNow developers, administrators, and support engineers
- What are the expected outcomes? Faster issue identification, efficient troubleshooting, and cleaner code
Prerequisites
- Required ServiceNow roles:
adminorscript_writefor Script Debugger - Access to System Logs (System Logs > All)
- Browser Developer Tools knowledge (Chrome DevTools, Firefox Developer Tools)
- Understanding of JavaScript fundamentals
Procedure
Server-Side Debugging
Logging Functions
ServiceNow provides multiple logging functions for server-side scripts. Choose based on log level and visibility requirements.
| Function | Log Level | Use Case |
gs.log(message, source) | Debug | Development/testing - legacy, prefer gs.debug |
gs.debug(message) | Debug | Detailed troubleshooting (requires debug enabled) |
gs.info(message) | Info | Informational messages for normal operations |
gs.warn(message) | Warning | Potential issues that don't stop execution |
gs.error(message) | Error | Errors that need attention |
Best Practice: Always include context in log messages:
// BAD - No context
gs.info('Record updated');
// GOOD - Full context
gs.info('[IncidentHandler] Incident ' + current.number + ' updated by ' + gs.getUserName() +
' - State changed from ' + current.state.getDisplayValue() + ' to ' + previous.state.getDisplayValue());Querying System Logs:
Tool: SN-Query-Table
Parameters:
table_name: syslog
query: source=IncidentHandler^sys_created_onONToday@javascript:gs.beginningOfToday()@javascript:gs.endOfToday()
fields: sys_created_on,level,message,source
limit: 50
order_by: sys_created_on
order_by_desc: trueScript Debugger
The Script Debugger allows step-by-step execution of server-side scripts.
Enabling the Script Debugger:
- Navigate to System Diagnostics > Script Debugger
- Click Enable Debugging for your session
- Set breakpoints in scripts using the debugger UI
- Trigger the script (e.g., update a record)
- Step through code using F10 (step over), F11 (step into), F5 (continue)
Debugging Business Rules:
Tool: SN-Query-Table
Parameters:
table_name: sys_script
query: collection=incident^active=true
fields: name,order,when,script,condition
limit: 50
order_by: orderKey Features:
- Variable inspection (hover over variables)
- Call stack visualization
- Watch expressions
- Conditional breakpoints
Session Debug Modules
Enable detailed logging for specific components during your session.
Common Session Debug Modules:
| Module | Purpose | Enable Path |
Session Debug | All session debugging | System Diagnostics > Session Debug > All |
Business Rules | Log BR execution | System Diagnostics > Session Debug > Business Rules |
SQL | Log database queries | System Diagnostics > Session Debug > SQL |
Security | ACL debugging | System Diagnostics > Session Debug > Security |
Client Scripts | Log client script data | System Diagnostics > Session Debug > Client Scripts |
Enable via Script:
// Enable business rule debugging for current session
gs.setProperty('glide.debugger.current.enabled', 'true');Script Execution History
Track script execution for troubleshooting.
Tool: SN-Query-Table
Parameters:
table_name: sys_script_execution_history
query: sys_created_onONLast 1 hour@javascript:gs.hoursAgo(1)@javascript:gs.nowDateTime()
fields: script,execution_time,status,error_message,sys_created_on
limit: 100
order_by: sys_created_on
order_by_desc: trueClient-Side Debugging
Browser Console Methods
| Method | Purpose |
console.log() | General logging |
console.info() | Informational messages |
console.warn() | Warning messages |
console.error() | Error messages |
console.table() | Display data in table format |
console.trace() | Show call stack |
ServiceNow-Specific:
// jslog - ServiceNow legacy logging (outputs to console when enabled)
jslog('Client script executed: ' + g_form.getValue('number'));
// Check if debug mode is enabled
if (window.NOW && NOW.debug) {
console.log('[DEBUG] Form loaded for: ' + g_form.getValue('sys_id'));
}Browser DevTools Debugging
Chrome DevTools Workflow:
- Open DevTools (F12 or Cmd+Option+I)
- Navigate to Sources tab
- Find client scripts under
scripts.do?sysparm_type=or in the page source - Set breakpoints by clicking line numbers
- Use Watch panel to monitor variables
- Use Scope panel to inspect local/closure variables
Useful DevTools Commands:
// In Console - Inspect form field
g_form.getValue('short_description');
// Get all form values
g_form.serialize();
// Check if field is mandatory
g_form.isMandatory('priority');
// Inspect GlideAjax response
// Set breakpoint in callback function to inspect 'response' objectNetwork Tab Analysis
Monitor AJAX calls and API requests:
- Open DevTools > Network tab
- Filter by XHR/Fetch
- Look for calls to:
xmlhttp.do- GlideAjax callsapi/now/- REST API callssysparm_processor- Form submissions
Common Network Issues:
- 401/403 errors - Authentication/ACL issues
- 500 errors - Server-side script errors
- Slow responses - Check Timing tab for breakdown
Transaction Logs
Analyzing Transaction Performance
Tool: SN-Query-Table
Parameters:
table_name: syslog_transaction
query: sys_created_onONLast 1 hour@javascript:gs.hoursAgo(1)@javascript:gs.nowDateTime()^urlLIKEincident
fields: url,response_time,user,sys_created_on,status
limit: 50
order_by: response_time
order_by_desc: trueSlow Query Detection
Tool: SN-Query-Table
Parameters:
table_name: syslog
query: messageLIKEslow query^sys_created_onONToday@javascript:gs.beginningOfToday()@javascript:gs.endOfToday()
fields: sys_created_on,message,source
limit: 100Debugging Business Rules
Understanding Business Rule Execution Order
Business rules execute in this order for each operation (insert, update, delete):
- before rules (order ascending) - Execute before database write
- after rules (order ascending) - Execute after database write
- async rules - Execute asynchronously
Critical: Order Matters!
Tool: SN-Query-Table
Parameters:
table_name: sys_script
query: collection=incident^active=true^when=before
fields: name,order,when,condition,script
limit: 100
order_by: orderDebugging Order Issues:
// Add to each business rule to trace execution order
gs.info('[BR Debug] ' + current.sys_class_name + ' - ' +
'Name: ' + current.getTableName() + '_BR_Name - ' +
'Order: ' + 100 + ' - ' +
'When: before - ' +
'Record: ' + current.number);Common Business Rule Debugging Patterns
Check if Script is Running:
(function executeRule(current, previous) {
gs.info('[BR_NAME] Script starting for: ' + current.getDisplayValue());
// Your logic here
gs.info('[BR_NAME] Script completed');
})(current, previous);Debug Condition:
// Log condition evaluation
gs.info('[BR_NAME] Condition check - current.state: ' + current.state +
', previous.state: ' + previous.state +
', Result: ' + (current.state != previous.state));Inspect Current vs Previous:
// Log all changed fields
var changes = current.changesLog();
if (changes) {
gs.info('[BR_NAME] Changes: ' + changes);
}Debugging Workflows and Flows
Workflow Debugging
Query Workflow Context:
Tool: SN-Query-Table
Parameters:
table_name: wf_context
query: active=true
fields: name,state,started,ended,id,scratchpad
limit: 50
order_by: sys_created_on
order_by_desc: trueCheck Workflow History:
Tool: SN-Query-Table
Parameters:
table_name: wf_history
query: context.active=false^sys_created_onONLast 7 days@javascript:gs.daysAgo(7)@javascript:gs.nowDateTime()
fields: activity,from_state,to_state,additional_info,sys_created_on
limit: 100
order_by: sys_created_on
order_by_desc: trueFlow Designer Debugging
Query Flow Executions:
Tool: SN-Query-Table
Parameters:
table_name: sys_flow_context
query: state!=complete^ORstate=error
fields: name,state,started,ended,error_message
limit: 50
order_by: sys_created_on
order_by_desc: trueEnable Flow Debug Mode:
- Open the flow in Flow Designer
- Click More Actions (three dots) > Debug
- Trigger the flow
- Review execution in the Debug panel
Common Error Messages and Solutions
"Record not found in table"
Cause: GlideRecord query returned no results Solution:
var gr = new GlideRecord('incident');
gr.addQuery('number', 'INC0000001');
gr.query();
if (gr.next()) {
// Record found
} else {
gs.warn('Record not found: INC0000001');
}"User not authorized"
Cause: ACL blocking access Solution:
- Enable Session Debug > Security
- Check ACL logs: System Logs > Security
- Query ACLs:
Tool: SN-Query-Table
Parameters:
table_name: sys_security_acl
query: name=incident
fields: name,operation,condition,script,role
limit: 100"Invalid script" or "Script error"
Cause: JavaScript syntax error or runtime exception Solution:
- Check System Logs for stack trace
- Use Script Debugger to step through
- Validate syntax with browser console
"Maximum execution time exceeded"
Cause: Script running too long (30+ seconds) Solution:
- Add GlideAggregate for counting instead of looping
- Use setLimit() to restrict result sets
- Move to Scheduled Job for large operations
"Mutual exclusion violation"
Cause: Same record being updated by multiple processes Solution:
- Check for recursive business rules
- Add condition to prevent re-entry:
if (current.update_in_progress) return;
current.update_in_progress = true;"Nested call limit exceeded"
Cause: Too many nested GlideRecord operations or recursive calls Solution:
- Refactor to reduce nesting depth
- Use GlideAggregate for counts
- Break into separate transactions
Tool Usage
MCP Tools (Claude Code/Desktop)
| Tool | Purpose |
SN-Query-Table | Query syslog, execution history, script records |
SN-Execute-Background-Script | Run diagnostic scripts on the instance |
SN-Get-Record | Retrieve specific log or script records |
REST API (ChatGPT/Other)
| Endpoint | Method | Purpose |
/api/now/table/syslog | GET | Query system logs |
/api/now/table/sys_script_execution_history | GET | Query script execution history |
/api/now/table/syslog_transaction | GET | Query transaction logs |
Native Tools (Claude Code)
| Tool | Purpose |
Bash | Execute curl commands for REST API |
Read | Read local script files for comparison |
Best Practices
- Always include context: Log function name, record identifier, and operation type
- Use appropriate log levels: Debug for development, Info for production tracing, Error for issues
- Clean up debug code: Remove or disable verbose logging before promoting to production
- Use conditional logging: Wrap debug statements in property checks
- Structured logging: Use consistent format:
[Component] Action - Details - Test in sub-production: Always debug in dev/test before touching production
Troubleshooting
Logs Not Appearing
Symptom: gs.log/gs.info statements not showing in System Logs Cause: Log level filtered or property disabled Solution:
- Check System Properties for
glide.log.level - Ensure
glide.script.log.levelallows your log level - Use
gs.error()which always logs
Script Debugger Not Triggering
Symptom: Breakpoints not hit when script executes Cause: Wrong session, script cached, or condition not met Solution:
- Ensure debugging enabled for YOUR session (not another admin)
- Clear cache: System Diagnostics > Cache Management > Flush Cache
- Verify script condition evaluates to true
Business Rule Not Firing
Symptom: Business rule appears inactive despite being enabled Cause: Condition not met, wrong table, or filter condition Solution:
Tool: SN-Query-Table
Parameters:
table_name: sys_script
query: name=YOUR_BUSINESS_RULE_NAME
fields: name,active,collection,when,order,condition,filter_condition,script
limit: 1Examples
Example 1: Trace Business Rule Execution
// Add to business rule for debugging
(function executeRule(current, previous) {
var startTime = new Date().getTime();
var brName = 'Validate Incident Priority';
gs.info('[' + brName + '] START - Record: ' + current.number);
try {
// Original business rule logic
if (current.priority == 1 && !current.assignment_group) {
gs.info('[' + brName + '] Setting mandatory assignment group');
gs.addErrorMessage('Critical incidents require an assignment group');
current.setAbortAction(true);
}
} catch (e) {
gs.error('[' + brName + '] ERROR: ' + e.message + '\nStack: ' + e.stack);
}
var duration = new Date().getTime() - startTime;
gs.info('[' + brName + '] END - Duration: ' + duration + 'ms');
})(current, previous);Example 2: Query Recent Errors
Tool: SN-Query-Table
Parameters:
table_name: syslog
query: level=error^sys_created_onONLast 24 hours@javascript:gs.hoursAgo(24)@javascript:gs.nowDateTime()
fields: sys_created_on,source,message
limit: 100
order_by: sys_created_on
order_by_desc: trueExample 3: Debug Client Script with GlideAjax
// Client Script
function onLoad() {
console.log('[MyClientScript] Form loaded, fetching data...');
var ga = new GlideAjax('MyAjaxProcessor');
ga.addParam('sysparm_name', 'getData');
ga.addParam('sysparm_record_id', g_form.getUniqueValue());
ga.getXMLAnswer(function(response) {
console.log('[MyClientScript] Response received:', response);
if (!response) {
console.error('[MyClientScript] Empty response from server');
return;
}
try {
var data = JSON.parse(response);
console.table(data);
} catch (e) {
console.error('[MyClientScript] Failed to parse response:', e);
}
});
}Example 4: Background Script for Log Analysis
Tool: SN-Execute-Background-Script
Parameters:
script: |
// Find all errors in last hour with stack traces
var gr = new GlideRecord('syslog');
gr.addQuery('level', 'error');
gr.addQuery('sys_created_on', '>=', gs.hoursAgo(1));
gr.orderByDesc('sys_created_on');
gr.setLimit(20);
gr.query();
var results = [];
while (gr.next()) {
results.push({
time: gr.sys_created_on.getDisplayValue(),
source: gr.source.toString(),
message: gr.message.toString().substring(0, 200)
});
}
gs.info('=== Recent Errors ===\n' + JSON.stringify(results, null, 2));
description: Analyze recent error logsRelated Skills
development/script-includes- Writing reusable server-side scriptsdevelopment/business-rules- Business rule development and best practicesdevelopment/client-scripts- Client-side scripting techniquesadmin/script-execution- System log configuration and management
References
In this repository184 other files it gives its agents.
- happy-platform-skillsSkill
- application-scopeSkill
- batch-operationsSkill
- configuration-validationSkill
- deployment-workflowSkill
- generic-crud-operationsSkill
- instance-managementSkill
- schema-discoverySkill
- script-executionSkill
- script-syncSkill
- smart-assessmentSkill
- task-analysisSkill
- task-summarizationSkill
- update-set-managementSkill
- user-provisioningSkill
- workflow-creationSkill
- workspace-insightsSkill
- approval-summarizationSkill
- approval-workflowsSkill
- catalog-builder-aiSkill
- catalog-item-generationSkill
- item-creationSkill
- multi-turn-orderingSkill
- request-fulfillmentSkill
- ui-policiesSkill
- variable-managementSkill
- ci-discoverySkill
- cmdb-search-analysisSkill
- data-qualitySkill
- impact-analysisSkill
- relationship-mappingSkill
- service-graph-diagnosisSkill
- activity-responseSkill
- csm-case-summarizationSkill
- chat-recommendationSkill
- email-recommendationSkill
- csm-kb-generationSkill
- resolution-notesSkill
- csm-sentiment-analysisSkill
- csm-sidebar-summarizationSkill
- csm-suggested-stepsSkill
- trending-topicsSkill
- automated-testingSkill
- business-rulesSkill
- client-scriptsSkill
- code-assistSkill
- code-reviewSkill
- data-importSkill
- fluent-sdkSkill
- glide-api-referenceSkill
- mcp-server-installationSkill
- mcp-serverSkill
- notificationsSkill
- performance-optimizationSkill
- scheduled-jobsSkill
- scripted-rest-apisSkill
- script-includesSkill
- servicenow-docs-mcpSkill
- test-generationSkill
- ui-actionsSkill
- The first 60 shown.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

