Debugging with AI: A Real Reference
Debugging with AI: A Real Reference
The mental model shift
Debugging used to be a solo activity. You read the trace, you formed a hypothesis, you tested it, you iterated. The loop was tight and entirely inside your head.
Debugging with AI is a different shape. It's a conversation, with you as the senior engineer and the AI as a fast junior who can read code at superhuman speed but doesn't know your system. The skills that matter shifted accordingly. You used to need pattern recognition for stack traces. You still do. But the bigger lift now is framing the problem well enough that the AI can help you think — which is a different skill, closer to writing a good bug report than to reading a debugger.
The mental shift I had to make: stop trying to be the one who finds the bug. Be the one who guides the search. The AI does the reading. You do the routing. When you stop trying to be the smart one in the room, debugging gets faster, not slower.
The 5 debugging patterns I use every week
These are the prompts I reach for. Each has a specific job. Knowing which to reach for first saves you the most time.
Pattern 1: "Read the error to me"
I paste the entire error — stack trace, message, any context lines — and ask the AI to explain what it means in plain language. Not "what's wrong with my code." Just "what is this error trying to tell me."
This is the right starting move 60% of the time. A surprising number of bugs get solved at this step alone, because the error message says exactly what's wrong and I missed it. Even when it doesn't solve the bug, getting the AI to articulate the error in clean prose narrows the search space immediately.
The prompt is exactly this:
"Read this error to me. Explain what it's actually saying, what category of bug this usually is, and what the most common causes are. Don't speculate about my specific code yet — just explain the error."
The "don't speculate about my specific code yet" part matters. If you skip it, the AI tends to leap to a fix before you've understood the problem. The result is a fix that addresses a symptom and breaks something else.
Pattern 2: "Show me what changed"
When something broke and worked an hour ago, the bug is in the diff. I paste the diff (git diff or the staged changes) and ask the AI to walk through it line by line looking for the most likely cause.
"Here's the diff between what worked and what broke. Walk through it line by line. For each change, ask: could this introduce the failure I'm seeing? Rank the top three suspect lines."
This is a forcing function. The AI can't say "let me look at your whole repo" — it has to focus on the actual change. Most regressions come from a small number of lines that touched a thing they shouldn't have. This pattern finds them fast.
Pattern 3: "Build a minimal reproduction"
When the bug is complex or intermittent, I stop debugging and start reducing. I ask the AI to help me build the smallest possible code that reproduces the issue.
"Help me build a minimal reproduction of this bug. Strip out anything that isn't needed to trigger the failure. The goal is the shortest code that consistently produces the error."
This sounds slow. It is fast. A minimal reproduction is the difference between hours of speculation and ten minutes of confirmation. It also turns "this bug is weird" into "this bug is reproducible," which is a different category of problem with a clear path to a fix.
Pattern 4: "Walk through the code as if I'm a junior dev"
When I think I understand the code but I'm wrong, this prompt surfaces the gap.
"Walk through this function as if you're explaining it to a junior dev. Don't skip steps. State what's in memory after each line. When you hit the part where you think the bug is, stop and tell me your hypothesis."
The "don't skip steps" is the part that does the work. The AI's first instinct is to summarize. You don't want a summary. You want a trace. Forcing the slow walk catches the assumptions I made that turned out to be wrong.
Pattern 5: "What would you check first?"
When I have no theory, I ask for one.
"Here's the bug. Here's the relevant code. I have no theory yet. Give me the top three things you'd check first, ranked by how cheap they are to verify versus how likely they are to be the cause."
The "ranked by cheapness to verify" part is critical. Without it, the AI gives you the most theoretically likely cause. What you want is the cheapest thing to rule out first, then the second cheapest. Debugging is search, and search runs faster when you take cheap probes first.
When to ask AI vs. read the trace yourself
The wrong move is to paste every error into the AI and let it think for you. The right move is to read the trace yourself for ten seconds first, form a one-sentence hypothesis, and then bring the AI in to either confirm or kill it.
Ask AI first when:
- The error message is unfamiliar to you
- The stack involves a library you don't know well
- You've already spent five minutes staring at the trace and aren't getting anywhere
- The bug is intermittent and you need a structured plan to catch it
Read the trace yourself first when:
- You wrote the code that's failing
- The error is in a category you've seen before
- The stack is short and the failing line is obvious
- You suspect a typo or a missing import (you'll find these faster than the AI will)
The judgment call: if you can articulate a specific hypothesis in one sentence, debug yourself first. If you can't, you're in search mode, and the AI is your partner.
The "I am stuck" workflow
This is the four-step escalation I use when nothing is working and I've been at a bug for more than 30 minutes.
Step 1: State the bug out loud. Open a fresh chat. Write the bug in two sentences. What's happening, what I expected. The act of writing it forces clarity. About 20% of the time I solve the bug while writing the description, which is humbling and also fine.
Step 2: List what I've tried. Three to five bullet points. What I tested, what I ruled out, what I assumed. The list does two things: it surfaces what I haven't tried, and it tells the AI not to waste my time suggesting things I've already done.
Step 3: Reset the context. I close the AI session and start a new one. The accumulated back-and-forth from the failed debugging attempt has poisoned the context. The AI is now anchored on theories that didn't work. A fresh session with the description and what-I've-tried list gives a clean read.
Step 4: Ask for the unexpected. I prompt: "Given what I've tried, what's a less obvious cause I should consider? Specifically, what would a senior engineer who has seen this kind of bug before check that I probably haven't?"
That last prompt is the unlock. It pulls out the weird ones — race conditions, cache invalidation, environment variable shadowing, the test that passed because of a side effect from a different test. The categories of bug you don't think to check because they don't show up in the first place you look.
If step 4 doesn't get you there, walk away. Touch grass. Come back in an hour. About 30% of the bugs I've been stuck on for 90+ minutes were solved within 10 minutes of coming back from a walk. The reason isn't mystical — it's that the search space resets when you stop thinking about it, and you come back with fresh attention.
Anti-patterns
Things I have done and learned not to do.
Dumping the whole codebase. The temptation is to paste your entire src/ directory into the prompt and let the AI figure it out. The result is universally worse than focused context. The AI gets confused by the noise. The relevant signal is buried. Be specific about which files matter. Two files with the right ones beats twenty with the wrong ones.
Asking "what's wrong with this code" before describing the bug. This produces a code review, not a debug session. The AI starts pointing out style issues and edge cases that have nothing to do with your actual failure. Always lead with the symptom: "When I do X, I get Y. I expected Z." Then bring the code in.
Letting the AI write a fix before you understand the bug. This is the worst one. The AI is very willing to write a patch. The patch will often even work. But if you didn't understand why the original code failed, you'll introduce the same class of bug somewhere else next week. Always require yourself to articulate the root cause in one sentence before accepting a fix.
Asking the AI to "verify the fix works." The AI cannot run your code. It will tell you the fix looks correct. You still have to run it. Treat AI verification of fixes as a sanity check, not a test. Run the actual test.
Long debugging sessions in a single chat. Past a certain point, the conversation starts to drift. The AI has too much accumulated context, much of which was wrong. If you've been debugging in one chat for 45 minutes and the bug isn't fixed, start a new chat. The reset compounds — a fresh context plus everything you've learned is faster than continuing to fight the old context.
The debugging-as-conversation pattern
The single biggest shift I made was thinking of debugging as a multi-turn conversation, not a single oracle query. The first prompt is rarely the one that finds the bug. It's the one that narrows the search.
The pattern looks like this: I describe the bug. The AI responds with three hypotheses. I tell it which is most plausible and why, and which is wrong and why. The AI updates its model and offers a deeper read on the remaining hypothesis. I run an experiment based on its suggestion. I come back with the result. We iterate.
This works dramatically better than dumping everything and asking for an answer. Each turn refines the search. Each of my responses gives the AI new information that wasn't in the original prompt — including information about what kinds of solutions are useful versus impractical given my system.
Debugging is search. Search is iterative. The AI is a search partner, not a search engine. Treat it that way and the loop closes faster.