skills/developer/debug-detective/stack-trace-decoder/SKILL.md
Use this skill when analyzing stack traces. Activate when the user has a stack trace to understand, needs to decode error traces, wants to find the root cause from a stack trace, is debugging crashes, or needs help interpreting exception traces.
npx skillsauth add latestaiagents/agent-skills stack-trace-decoderInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Parse, understand, and extract actionable insights from stack traces.
Error: Cannot read properties of undefined (reading 'map')
at processItems (/app/src/services/processor.js:45:12)
at async handleRequest (/app/src/handlers/api.js:23:5)
at async Router.handle (/app/node_modules/express/router.js:156:3)
at async Layer.handle_request (/app/node_modules/express/layer.js:95:5)
Components:
Error: [Error Type]: [Error Message]
at [Function Name] ([File Path]:[Line]:[Column])
│ │ │ │ │
│ │ │ │ └─ Column number
│ │ │ └─ Line number
│ │ └─ File path
│ └─ Function where error occurred
└─ "at" indicates stack frame
Traceback (most recent call last):
File "/app/main.py", line 45, in process_data
result = transform(data['items'])
File "/app/utils.py", line 23, in transform
return [item.upper() for item in items]
TypeError: 'NoneType' object is not iterable
Note: Python traces read bottom-to-top (error at bottom).
java.lang.NullPointerException: Cannot invoke method on null object
at com.example.service.UserService.getProfile(UserService.java:89)
at com.example.controller.UserController.showProfile(UserController.java:45)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:897)
Caused by: java.sql.SQLException: Connection refused
at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2181)
... 15 more
Note: Java traces can have "Caused by" chains showing root cause.
The first frame (or last in Python) in YOUR code is usually most important.
function findRelevantFrame(trace: string, appPaths: string[]): Frame | null {
const frames = parseStackTrace(trace);
// Skip framework/library frames
for (const frame of frames) {
if (appPaths.some(p => frame.file.includes(p))) {
return frame;
}
}
return frames[0]; // Fallback to first frame
}
// Example: Find first frame in 'src/' directory
const relevantFrame = findRelevantFrame(trace, ['src/', 'app/']);
interface StackFrame {
functionName: string;
file: string;
line: number;
column?: number;
isNative: boolean;
isAsync: boolean;
}
function parseJavaScriptTrace(trace: string): StackFrame[] {
const lines = trace.split('\n');
const frames: StackFrame[] = [];
for (const line of lines) {
// Match: "at functionName (file:line:col)"
const match = line.match(/at\s+(?:(async)\s+)?(\S+)\s+\((.+):(\d+):(\d+)\)/);
if (match) {
frames.push({
isAsync: match[1] === 'async',
functionName: match[2],
file: match[3],
line: parseInt(match[4]),
column: parseInt(match[5]),
isNative: match[3].includes('native') || match[3].includes('node:')
});
}
}
return frames;
}
const ERROR_PATTERNS = {
// JavaScript
'TypeError.*undefined': {
cause: 'Accessing property on undefined value',
fix: 'Add null check or optional chaining'
},
'TypeError.*not a function': {
cause: 'Calling something that is not a function',
fix: 'Check if the method exists and is spelled correctly'
},
'RangeError': {
cause: 'Value out of allowed range (array size, recursion)',
fix: 'Check for infinite recursion or large data'
},
'SyntaxError': {
cause: 'Invalid JavaScript syntax',
fix: 'Check for JSON parse errors or eval issues'
},
// Python
'KeyError': {
cause: 'Dictionary key does not exist',
fix: 'Use .get() with default or check key existence'
},
'AttributeError.*NoneType': {
cause: 'Calling method on None value',
fix: 'Add None check before method call'
},
// Java
'NullPointerException': {
cause: 'Calling method on null reference',
fix: 'Add null check or use Optional'
},
'ClassCastException': {
cause: 'Invalid type cast',
fix: 'Check object type before casting'
}
};
function identifyErrorPattern(trace: string): ErrorInfo | null {
for (const [pattern, info] of Object.entries(ERROR_PATTERNS)) {
if (new RegExp(pattern, 'i').test(trace)) {
return info;
}
}
return null;
}
// Error: Cannot read properties of undefined (reading 'email')
const email = user.profile.contact.email;
// ↑ ↑ ↑
// Any of these could be undefined
Solution:
const email = user?.profile?.contact?.email;
// Or
const email = user && user.profile && user.profile.contact?.email;
Error: Something went wrong
at processData (app.js:10) // Where error was thrown
// Gap - async boundary
at async Promise.all // No intermediate frames
Solution: Use Error.captureStackTrace or async stack traces:
// Enable in Node.js
Error.stackTraceLimit = 50;
// Or use --async-stack-traces flag
Error: t is not a function
at e.render (main.a3f2b1c.js:1:45678)
at t.update (main.a3f2b1c.js:1:23456)
Solution: Use source maps:
# Decode with source-map-cli
source-map resolve main.a3f2b1c.js.map 1 45678
ServiceException: Failed to process user
at UserService.process(UserService.java:50)
Caused by: DatabaseException: Query failed
at Database.query(Database.java:120)
Caused by: SQLException: Connection refused
at Driver.connect(Driver.java:80)
Reading: Start from the innermost "Caused by" - that's the root cause.
import { SourceMapConsumer } from 'source-map';
async function decodeMinifiedTrace(
trace: string,
sourceMap: string
): Promise<string> {
const consumer = await new SourceMapConsumer(JSON.parse(sourceMap));
const frames = parseJavaScriptTrace(trace);
const decoded = frames.map(frame => {
if (frame.file.includes('.min.') || frame.file.includes('.bundle.')) {
const original = consumer.originalPositionFor({
line: frame.line,
column: frame.column || 0
});
return {
...frame,
file: original.source || frame.file,
line: original.line || frame.line,
column: original.column || frame.column,
functionName: original.name || frame.functionName
};
}
return frame;
});
consumer.destroy();
return formatFrames(decoded);
}
Decode and explain this stack trace:
[paste stack trace]
Provide:
1. **Error Summary** - What went wrong in plain English
2. **Root Cause Location** - The file and line to look at
3. **Call Chain** - How the code got there
4. **Likely Cause** - What probably triggered this
5. **Suggested Fix** - How to resolve it
Also note if:
- This looks like a common pattern
- The error is in our code vs library code
- Additional context would help
function compareTraces(trace1: string, trace2: string): TraceComparison {
const frames1 = parseStackTrace(trace1);
const frames2 = parseStackTrace(trace2);
// Find common frames
const common = frames1.filter(f1 =>
frames2.some(f2 => f1.file === f2.file && f1.line === f2.line)
);
// Find divergence point
let divergeIndex = 0;
for (let i = 0; i < Math.min(frames1.length, frames2.length); i++) {
if (frames1[i].file !== frames2[i].file || frames1[i].line !== frames2[i].line) {
divergeIndex = i;
break;
}
}
return {
areSameError: common.length > frames1.length * 0.8,
commonFrames: common,
divergencePoint: divergeIndex,
uniqueToFirst: frames1.filter(f => !common.includes(f)),
uniqueToSecond: frames2.filter(f => !common.includes(f))
};
}
development
Test skills for correct activation, content quality, and regression — both automated checks (frontmatter validity, lint) and manual verification (query-suite activation testing). Covers CI integration and how to catch skill regressions before users do. Use this skill when adding skills to a repo, setting up CI for a skill library, or debugging "the skill exists but doesn't work". Activate when: test skills, validate skills, skill CI, skill linting, skill activation test, skill regression.
documentation
Write the YAML frontmatter for a SKILL.md file so it activates reliably — name, description, and activation keywords that the model matches against. Covers length, tone, and the most common frontmatter mistakes. Use this skill when authoring a new skill, fixing a skill that isn't auto-activating, or reviewing skills for publication. Activate when: SKILL.md frontmatter, skill description, skill activation, skill YAML, write a skill, author a skill.
development
Design skills that fire at the right moment — neither over-eager (noise) nor under-eager (silent). Covers activation specificity, trigger phrases, disambiguation between overlapping skills, and debugging activation. Use this skill when multiple skills could fire on the same query, a skill never fires, or a skill fires too often. Activate when: skill won't activate, skill over-activates, overlapping skills, skill triggers, skill selection, skill disambiguation.
development
Structure SKILL.md content so the model reads just enough — concise summary up front, progressively deeper detail, examples on demand. Covers section ordering, length budgets, when to split into multiple skills. Use this skill when writing or refactoring a skill body, one skill has grown too long, or a skill is wordy but not useful. Activate when: SKILL.md structure, skill content, skill too long, split skill, progressive disclosure, skill body.