Debugging with Claude
Claude in VS Code: Pair Programming
Debugging is where having a knowledgeable second pair of eyes pays off immediately. Claude can read a stack trace, explain what went wrong, suggest root causes, and propose a fix — often faster than you could work through it alone. But there's a discipline to debugging with AI: the quality of Claude's diagnosis is directly proportional to the quality of the information you give it. This chapter covers what to send, how to ask, and when to reach for the debugger instead.
Reading a Stack Trace with Claude
A stack trace tells a story — but reading it bottom-up (where the error originates) is different from reading it top-down (how you got there). Claude is good at translating the trace into plain language and pointing at the line that matters. The key is sending the whole trace, not just the error message.
File "app/api/routes/orders.py", line 47, in create_order entry point
result = order_service.process(payload)
File "app/services/order_service.py", line 112, in process
user = db.query(User).filter_by(id=payload.user_id).one()
File "sqlalchemy/orm/query.py", line 2691, in one read from here down
raise NoResultFound()
sqlalchemy.orm.exc.NoResultFound: No row was found for one() actual error
When sending a trace to Claude:
- Include the full trace — not just the final error line. The frames above it show how the code got there.
- Include the relevant source lines — the trace shows line numbers, but not the surrounding context. Open the file and paste the function Claude is being asked to diagnose.
- Describe what you were doing — "this happens when I try to create an order for a user who signed up yesterday." Conditions that trigger the bug are often the key to understanding it.
What Information to Send
- The complete error message and stack trace
- The function or block where the error occurs
- What you were doing / what input triggered it
- What you expected to happen
- Recent changes to the code ("I refactored this yesterday")
- The environment it fails in vs works in
- Any related function that calls or is called by the failing code
- Data shape or sample values that trigger the error
- What you've already tried and ruled out
- Whether it's intermittent or consistent
- Library / framework versions if version-specific
- Logs from immediately before the error
- The inner-most exception (sometimes wrapped)
- The file and line number from your code (not the library)
- Type information if it's a type error
- The actual vs expected value if it's an assertion
Explain vs Fix — Know Which to Ask For
There's an important difference between asking Claude to explain a bug and asking it to fix a bug. Both are useful, but they serve different purposes and the one you choose affects how much you learn.
You understand the root cause before any code changes. Better for: bugs in code you're unfamiliar with, subtle logic errors, or anything where you want to stay in control of the fix.
Fastest path to a working change. Better for: well-understood errors (typo, missing import, off-by-one), boilerplate fixes, or when you're under time pressure.
Bug Categories and How to Ask
Claude vs the Debugger — When to Use Which
| Reach for Claude when… | Reach for the debugger when… |
|---|---|
| You have a stack trace and want it explained | You need to inspect actual runtime values at a specific line |
| The bug is in logic you can read statically | The bug only manifests under specific timing or load conditions |
| You want to understand why the code fails, not just where | You need to step through a complex execution path frame by frame |
| The error message is cryptic and needs translation | You're dealing with a memory issue, thread race, or async timing bug |
| You want to brainstorm possible root causes | You need to watch a variable change across many iterations |
| The bug is in a third-party library and you want to understand its behaviour | The execution path is long and branching and you can't mentally model it |
The two tools complement each other. A common workflow: use Claude to identify the likely cause and the suspect lines, then set a breakpoint at exactly those lines in the debugger to confirm. This is faster than stepping through from the start.
When Claude's Diagnosis Is Wrong
Claude can misdiagnose a bug — especially when the cause is environmental (a specific data state, a platform difference, a version incompatibility) rather than visible in the static code. If Claude's suggested fix doesn't resolve the problem:
- Tell Claude what happened — "I tried that fix and still get the same error. Here's the new trace." This is the most important thing you can do — don't start over, iterate.
- Add more context — if Claude missed something, it's usually because you didn't include it. What's in the database? What's the actual value of the variable? What changed recently?
- Ask for alternative hypotheses — "If that's not the cause, what else could explain this?" Claude will generate other candidates to investigate.
- Try rubber duck debugging — ask Claude to ask you questions: "Ask me questions to help diagnose this." Often the act of answering surfaces what you'd forgotten to include.