~/VibeHandbook
$39

Chapter 07

Debugging With AI

Every program you build will break. That is not a sign you are doing it wrong — it is the normal state of software. The difference between a frustrating afternoon and a five-minute fix is method. When you debug by vibe coding, you are not the one staring at the stack trace until it makes sense. You are the director: you reproduce the problem, gather the right evidence, and hand the AI a tight, well-framed case so it can do the heavy lifting. This chapter gives you a repeatable process for exactly that.

The core mindset

The single biggest mistake beginners make is pasting "it doesn't work, fix it" into the chat and hoping. The AI cannot see your screen, your data, or what you expected to happen. It only knows what you tell it. Debugging with AI is mostly about feeding it the right context so it can reason instead of guess.

A good bug report — to a human or an AI — answers three questions:

  • What did you do? (the steps to trigger it)
  • What did you expect to happen?
  • What actually happened? (the error, the wrong output, the crash)

If you can answer those three, you are already ahead of most people.

A debugging checklist

Work through these in order. Skipping straight to "fix it" is what sends the AI in circles.

  1. Reproduce it reliably. Find the exact steps that make the bug happen every time. A bug you can't reproduce is one you can't confirm you fixed.
  2. Read the actual error. Don't skim. The error message and the top of the stack trace usually name the file and line where things went wrong.
  3. Gather the context. Collect the error text, the stack trace, the relevant code, and a one-line description of what you expected.
  4. Hand the AI the full picture. Paste all of the above in one message. Let it form a hypothesis.
  5. Form a hypothesis, not a fix. Ask "what could cause this?" before "fix this." A wrong fix on a wrong theory wastes time.
  6. Add logging to test the hypothesis. Confirm what the code is actually doing before changing it.
  7. Binary-search the problem. Narrow down where it breaks by cutting the suspect area in half repeatedly.
  8. Fix the root cause, not the symptom. Make sure the fix addresses why it broke, not just the visible glitch.
  9. Verify the fix and check for regressions. Re-run the reproduction steps. Then make sure nearby features still work.

Feeding the AI the right context

This is where most of your leverage is. When you report a bug, include:

  • The error message, verbatim. Copy it exactly — don't paraphrase.
  • The stack trace, especially the top few lines.
  • The relevant code — the function that threw, plus anything it calls.
  • What you expected versus what happened.

Here is what a strong debugging prompt actually looks like:

I'm getting an error when I submit the signup form. Here's the full output:

TypeError: Cannot read properties of undefined (reading 'email')
    at validateUser (src/auth/validate.js:14:23)
    at handleSignup (src/routes/signup.js:31:10)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)

Steps to reproduce: fill in the form, click "Sign up".
Expected: a "Welcome" message.
Actual: the page goes blank and the error above appears in the console.

Here is validate.js (lines around 14):
[paste the function]

And here is the handleSignup function that calls it:
[paste the function]

What could be causing this, and how do I confirm it before changing anything?

Notice that last line. You are asking for a hypothesis and a confirmation step, not an immediate edit. That keeps the AI honest.

Once the AI proposes a cause, don't just accept it. Test it cheaply. The cheapest test is usually a log line.

Ask the AI to add temporary logging:

"Before we change anything, add a console.log (or print) that shows the value of user right before line 14, so we can see whether it's actually undefined."

Run it, paste the output back. Now you have evidence, not a theory. Maybe user is undefined — confirming the hypothesis. Maybe it's fine and the real culprit is one level up. Either way you've moved forward.

When the bug lives somewhere in a long process and you can't tell where, use binary search. Cut the suspect region in half: add a log at the midpoint. Did the value look correct there? Then the bug is after it — search that half. Did it look wrong already? The bug is before — search that half. Each step halves the search space, so even a thousand-line path narrows down in about ten checks. Tell the AI explicitly: "Help me bisect this — where's the halfway point I should log?"

Root cause versus symptom

The most tempting trap in debugging is the patch that makes the error disappear without fixing the cause. If user is undefined and you "fix" it with if (user) { ... }, the error stops — but now signups silently do nothing, which is worse. The real question is why is user undefined here? Maybe the database lookup failed. Maybe a field was renamed. Maybe an await is missing upstream.

When the AI proposes a fix, ask it:

  • "Is this fixing the cause or hiding the symptom?"
  • "What was the original reason the value was wrong?"
  • "Could this same root cause break anything else?"

A root-cause fix usually makes the code simpler or clearer. A symptom patch usually adds a guard, a try/catch that swallows errors, or a default value that papers over the real problem. Be suspicious of the second kind.

When the AI goes in circles

Sometimes the AI suggests a fix, it doesn't work, it suggests another, that doesn't work either, and you're three "try this instead" loops deep. This is a signal, not a dead end. Do this:

  • Stop and reset the context. Start a fresh message summarizing everything you now know for certain (confirmed by logs), not everything you've tried.
  • State what you've ruled out. "We confirmed user is undefined and the DB query returns null. The query string looks right. So the problem is upstream of the query." This stops the AI from re-suggesting dead ends.
  • Ask it to explain, not fix. "Walk me through, step by step, how user gets its value from the request to line 14." Forcing an explanation often surfaces the gap.
  • Add more logging, not more guesses. When theories run out, evidence is the way forward.
  • Shrink the problem. Ask the AI to help you build the smallest possible snippet that still reproduces the bug. Often the bug becomes obvious once the noise is gone — and if it doesn't reproduce in the small version, you've learned the cause is in what you removed.

The takeaway

Debugging with AI is not about knowing the answer. It's about running a disciplined process: reproduce, gather context, hypothesize, confirm with logging, bisect, and fix the root cause. Your job as the director is to keep the investigation grounded in evidence and to recognize when the loop has gone stale. Do that, and most bugs stop being mysteries and start being just another step in building real software.

Want it offline?

Get the PDF + EPUB + downloadable prompt library + version updates.

$ Get the PDF — $39