Debugging with Claude Code: reproduce first, then prove the root cause
Paste a stack trace into Claude Code and ask for a fix, and you'll usually get one within a minute. Sometimes it fixes the bug. Sometimes it adds a null check that hides it. The difference is whether anyone reproduced the bug and proved the cause first.
Senior engineers debug in a fixed order: reproduce, find the cause, prove it, then fix. Claude Code can follow the same order, and it's fast at every step. It just won't do it unless you ask. Here's the workflow.
1. Reproduce before you touch anything
A bug you can't reproduce is a bug you can't prove you fixed. So the first job is a reproduction that fails today, fails for the reported reason, and is as small as possible.
- Write down expected, actual, trigger and environment in one line each. If expected or actual is missing, ask one precise question instead of guessing.
- Try the cheapest level first: a unit test on the suspect function, then an integration test through the public entry point, then a standalone script.
- Make it assert the expected behavior, so it passes once the bug is fixed.
- Check it fails for the right reason. A test that fails because of a typo in the setup isn't a reproduction.
Tell Claude explicitly: "Don't fix anything yet. Give me a failing test." That one sentence prevents most premature fixes.
2. Find the cause with ranked hypotheses
With a failing test in hand, ask for the root cause, not a fix. A good root-cause pass:
- reads the stack trace from the bottom of your own code, not the framework frames;
- lists two to four hypotheses, ranked by likelihood;
- tests each with the cheapest experiment: a log line, a changed input, an env flag;
- calls a cause confirmed only when toggling it makes the failure appear and disappear.
The output should look like evidence, not a story:
Root cause (Confirmed): src/auth/session.ts:42 reads user.org.id, but invited
users have org = null until they accept. Added in a1b2c3d.
Evidence: repro test fails; with a null check at :42 it passes; reverting
the check makes it fail again.
Ruled out: stale cache (still fails with CACHE_DISABLED=1).
Fix options:
1. Treat org as optional at :42 (smallest change).
2. Don't create a session until the invite is accepted (closes the whole class).
Also affected: src/billing/plan.ts:17 makes the same assumption.
Note the last line. Once the real cause is known, finding the other places with the same assumption is cheap, and it's where the next bug report would have come from.
3. For regressions, let git find the commit
If it worked last week, don't read code at all. Have Claude write a small check script that exits 0 when the behavior is good and 1 when it's bad, then run:
git bisect start
git bisect bad HEAD
git bisect good v2.3.0
git bisect run ./scripts/check-regression.sh
git bisect reset
Ask for three things back: the first bad commit, the hunk in it that broke things, and proof from reverting just that hunk. Use exit code 125 in the script for commits that can't be tested (for example, ones that don't build), so bisect skips them instead of blaming them.
4. Fix flaky tests, don't retry them
Left alone, AI fixes for flaky tests reach for retries, longer timeouts or skip. Ban all three. Instead:
- Measure the flake rate by running the test in a loop, e.g. 50 times.
- Find the source of nondeterminism: timing, test order, shared state, randomness, time zones or network.
- Make it fail every time by forcing that condition (a fixed seed,
TZ=Pacific/Auckland, a reversed test order). - Fix the cause, then run the loop again to show the rate is zero.
Then write it down
For anything that reached users, finish with a short blameless postmortem: impact, root cause, contributing factors, how it was detected and action items with owners. Claude can draft it from the fix, the commits and the timeline. Tell it never to invent a number or a time; missing facts should be marked as missing.
Turn the workflow into skills
Each step above works as a prompt, but it sticks when it's a skill Claude loads on its own whenever you say "reproduce this" or "find the root cause". Our guide on writing Claude Code skills shows how. For review, see code review with Claude Code.
Or use the Debugging Pack below: five ready skills for exactly these steps, from repro to postmortem.