How to Get an AI Coding Agent to Explain a Stack Trace
A worked example showing the exact prompt structure that gets an AI coding agent to read the failing frame of a stack trace instead of guessing from the error message alone.
To get an AI coding agent to explain a stack trace, paste the full trace verbatim, not a paraphrase, then point it at the specific frame that lives in your own code rather than in a framework or the Node.js runtime. Ask it to open that file, read the surrounding lines, and trace the value that's undefined or null back to where it originates. A one-line error message plus "fix this" gets you a guess. A full trace plus a request to read the actual failing frame and its caller gets you a diagnosis. The gap between those two outcomes is widest on multi-frame traces, where the real bug is rarely on the line the exception points to.
Why "Just Paste the Error" Falls Apart on Real Traces
Pasting only the error message, or even a screenshot of a red banner in your terminal, gives the agent an exception type and maybe a one-line description. It has no file contents, no line numbers it can trust, and no idea which frame is application code versus a library doing its job correctly. So it pattern-matches against common causes for that error class and proposes the statistically likely fix: add optional chaining, wrap the call in a try/catch, add a null check. Sometimes that patches the symptom. It rarely explains why the value was missing in the first place, which means the same bug tends to resurface somewhere else once an agent starts swallowing errors instead of surfacing them.
Multi-frame traces make this worse. A trace with three or four frames usually means the bad value was created several function calls away from where it finally blew up. The frame that throws is often just the first place code tried to actually use the value. If you only show the agent that one frame, it can only guess at what upstream code passed in, and it will guess wrong roughly as often as a developer would guessing from the same slice of information.
What a Useful Debugging Prompt Actually Includes
A prompt that reliably produces a real diagnosis, not a guess, has four ingredients. Skip any one of them and you are back to pattern matching.
1) The complete trace, unedited. Every frame, including the ones that look like framework noise. You don't know in advance which frame matters, and trimming the trace to "the relevant part" is exactly the judgment call you want the agent making with full information, not you making for it before the agent even sees it.
2) A note on which frames are yours. Node.js traces mix your application code with framework internals and node_modules paths. Tell the agent explicitly which file paths belong to your project, for example "everything under src/ is my code, ignore frames from node_modules unless they're clearly relevant." This stops it wasting a turn speculating about Express internals instead of reading your service file.
3) An explicit instruction to open and read the source at the failing frame and at least its direct caller. Most agents can read files in the project when told to, but a bare error paste doesn't prompt that behavior reliably. Say it outright: "open orderService.js around line 42 and orderController.js around line 15 before you propose anything."
4) A request to trace the offending variable backward, not just patch where it breaks. Ask where the value comes from, which function produced it, and whether it could legitimately be missing at that point or whether something upstream failed to set it. This is the difference between a fix and a bandage, and it's the same discipline that stops an agent from repeating the same mistake on the next task, because the actual cause got documented instead of papered over.
A Worked Example: A Node.js TypeError Across Three Frames
Here's a small, realistic case. An Express route lists a user's orders. The route calls a controller, the controller calls a service, and the service queries the database. Somewhere in that chain, a value that should have been a user object is undefined by the time it reaches the service.
The trace looks like this: TypeError: Cannot read properties of undefined (reading 'id') at getUserOrders (/app/src/services/orderService.js:42:19), at async listOrders (/app/src/controllers/orderController.js:15:22), at async /app/src/routes/orders.js:8:5.
The relevant line in orderController.js, line 15, reads: const orders = await getUserOrders(req.user). The relevant line in orderService.js, line 42, reads: const orders = await db.orders.findMany({ where: { userId: user.id } }).
The Bad Prompt
"I'm getting TypeError: Cannot read properties of undefined (reading 'id'). Can you fix it?" Handed only that sentence, most agents will add a guard clause: if (!user) throw new Error('user required') or user?.id with a fallback. That stops the crash. It does not explain why req.user was undefined on that request, so the same request will now fail with a different, vaguer error, or silently return no orders instead of the user's actual orders.
The Good Prompt
"Here's the full stack trace: [paste all three frames]. Everything under src/ is my code. Open orderService.js around line 42 and orderController.js around line 15 and read the surrounding twenty lines of each. The error says user.id is being read on undefined, so trace req.user backward: find the middleware or route definition that's supposed to set req.user, check whether it runs before this route, and tell me why it might not have run for this request before proposing a fix." That last clause matters as much as the file pointers. It tells the agent what counts as enough context to reason from instead of stopping at the first plausible-looking cause.
Given that prompt, an agent that actually opens the files will find that the orders route was registered before the authentication middleware that attaches req.user, probably because a new route file got mounted in routes/index.js above the auth middleware instead of below it. The real fix is reordering middleware registration, not guarding against a null user on every downstream function that happens to touch it. That's a two-line change in one file instead of defensive checks scattered across three.
A Prompt Template You Can Reuse
A template you can paste and fill in each time saves you from reconstructing this from scratch under time pressure. It has five slots: the full trace pasted verbatim, a one-line note on which paths are your code, an instruction to open the failing frame plus its direct caller before answering, the specific variable or value to trace backward to its origin, and a closing instruction to explain the root cause before writing a fix, not simultaneously with it. Separating explanation from fix is deliberate. If you ask for both at once, an agent will often write the fix first and back-fill a plausible-sounding explanation to match it, rather than diagnosing first. This matters whichever AI coding tool you're using, since the failure mode is about prompt structure, not any particular vendor's model.
When to Point at a Frame vs Let the Agent Explore
Pointing directly at a frame is faster when the trace has clean, readable file paths and line numbers that map to your actual source, which is normally true for server-side Node.js and Python code running unminified. It breaks down for frontend errors from a production bundle, where the trace shows a minified file and a column number instead of a meaningful function name. In that case, either generate and attach source maps before asking the agent to read the trace, or explicitly tell it the trace is minified and ask it to search the codebase by the error message text and surrounding logic instead of by file and line number. Node's own docs cover how to enable source maps for stack traces with the --enable-source-maps flag, and it's worth turning on for any service you expect to debug this way, in staging if not production.
Letting the agent explore more broadly, rather than pointing at one file, pays off when a trace crosses an async boundary or a queue, where the frame that throws has no direct caller in the same request. Tell it to search for where the failing function gets invoked across the codebase rather than assuming a single call site, since async traces in Node.js often only show the immediate promise chain, not the original call that kicked off the work. The Error.stack property itself is just a formatted string with no guaranteed structure across engines, which is part of why handing over the raw text and letting the agent parse it in context works better than trying to pre-process it yourself.
Why does an AI agent sometimes fix the wrong line in a stack trace?
Usually because it was only shown the top frame, or wasn't told to read the file before answering, so it pattern-matched the error type to a common fix rather than confirming what the surrounding code actually does. Giving it the full trace and an explicit read-before-answer instruction fixes most of these cases.
What should I paste when an AI agent can't see my file system?
Paste the full trace plus the contents of the failing file and its direct caller, at minimum thirty lines of surrounding context each. If the agent has no file access at all, it can only reason from what you paste, so err on the side of pasting more of the function, not less.
Do I need to explain what a stack trace is to the agent?
No. Current coding agents already know the format for Node.js, Python, and most common runtimes. What they need from you is which frames are your code, what counts as project context, and an instruction to read before answering, not a primer on what a stack trace is.
How do I handle stack traces from minified or bundled JavaScript?
Enable source maps for the build you're debugging so line numbers map back to real source, or tell the agent explicitly that the trace is minified and have it search the codebase for the error text and surrounding logic instead of trusting the file and line number in the trace.
How did this land?
About the author

Developer Advocate
Steve builds something with Swarmz every week and writes up what worked, what broke, and what he'd do differently. Tutorials and hands-on guides are his lane.


