You know the pattern. The assistant says "I've fixed the issue." It hasn't. You paste the error again. It changes three files, one of which had nothing to do with the bug. Now there are two errors. Twenty minutes later you're on attempt eleven, and the code is worse than when you started.

This isn't bad luck. A loop usually means the assistant is guessing, and every guess adds context that makes the next guess worse. Retrying the same prompt won't fix that. Changing the conditions will.

Here's the routine we use to get out of loops, roughly in order of how often each step solves it.

Step 0: Notice you're in a loop

Set a rule: if two attempts at the same bug fail, stop and reset. Don't wait for attempt ten. Other signs you're looping:

  • The same error comes back with a slightly different line number.
  • The assistant re-adds code it removed two turns ago.
  • Fixes start touching files that have nothing to do with the bug.
  • It says "this should now work" without having run anything.

Step 1: Make every attempt reversible

Before anything else, make sure you can go back. With an agent that edits files directly, commit before each attempt:

git add -A && git commit -m "checkpoint: before AI fix attempt" # after the attempt, see exactly what changed git diff --stat HEAD # didn't help? throw it all away git reset --hard HEAD 

(git reset --hard discards uncommitted changes, which is exactly what you want here because you just checkpointed.)

That git diff --stat line is underrated. If you asked for a fix in the login form and the diff touches eight files, reject it on sight.

Step 2: Start a fresh session

Long conversations collect failed attempts, half-reverted code and wrong theories. The assistant treats all of it as context. Opening a new chat or agent session with a clean summary often solves in one turn what the old thread couldn't solve in ten.

Write the summary yourself. Don't ask the looping session to summarise, or its wrong theory comes along too.

Step 3: Ask for a diagnosis, not a fix

The most useful change you can make is to forbid code until the cause is understood. Something like:

Don't write or change any code yet. Bug: [one sentence: what happens vs. what should happen] Steps to reproduce: [1, 2, 3] Exact error and stack trace: [paste in full, not paraphrased] Relevant files: [list them] Give me: 1. The three most likely root causes, ranked, each with the evidence from the code or error that supports it. 2. For the top cause, one small check (a log line, a query, a test) that would confirm or rule it out. Wait for the result of that check before proposing a fix. 

This turns the assistant from a guesser into an investigator. Often step 2 of its own answer shows the real problem in under a minute.

Step 4: Shrink the problem

If the diagnosis is still vague, reduce what the assistant can see and touch:

  • Reproduce it in isolation. Can you trigger the bug with one function call, one API request or one test? If you can write a failing test, ask the assistant to make that test pass and change nothing else.
  • Bound the edit. Say which files it may change. "Only edit lib/auth.ts. If you think another file needs changing, tell me why instead of changing it."
  • Bisect. If it worked last week, git bisect will find the commit that broke it faster than any conversation:
git bisect start git bisect bad # current commit is broken git bisect good <last-good-sha> # test each commit git checks out, then mark it: git bisect good # or: git bisect bad git bisect reset # when done 

Then give the assistant the one offending diff. A 30-line diff is a much easier problem than a whole codebase.

Step 5: Give it real evidence, not your interpretation

Assistants loop when they're working from your summary of the problem rather than the problem itself. Paste:

  • the full error and stack trace, not "it says something about undefined";
  • the actual network response (status code and body from your browser's dev tools Network tab);
  • the server logs, not just the browser console. Many "frontend" bugs are a 500 from an API route.

If it's a data bug, add the relevant row(s) from the database, with anything sensitive removed. Don't paste real API keys, customer data or production secrets into any AI tool.

Step 6: The "works locally, fails in production" special case

This one deserves its own checklist, because assistants are especially bad at it: they can't see your hosting environment, so they keep editing code that's fine. Before prompting at all, check:

  • [ ] Environment variables. Is every variable set in the hosting dashboard, for the right environment (preview vs production)? Did you redeploy after adding them?
  • [ ] Client vs server variables. In frameworks like Next.js or Vite, only prefixed variables reach the browser, and they're baked in at build time.
  • [ ] URLs. Hard-coded localhost in API calls, OAuth redirect URLs or webhook endpoints.
  • [ ] Auth callback settings. Your auth provider's allowed redirect URLs include the production domain.
  • [ ] Case-sensitive imports. ./Components/Button works on macOS and Windows but fails on Linux build servers.
  • [ ] Runtime differences. Code that needs Node APIs running on an edge runtime, or a function hitting a timeout.
  • [ ] Build logs, not just runtime logs. The answer is often a warning you scrolled past.

Then give the assistant the production error plus the result of this checklist. "Env vars confirmed set, redeployed, error is a 500 from /api/generate with this body" gets you a real answer.

Step 7: Know when to stop using the assistant for this bug

Sometimes the fastest path is to read the code yourself, or the library's docs and its issue tracker. That's especially true when:

  • the bug is in a library version newer than the model's training data, so it confidently uses an old API;
  • the problem is configuration in a dashboard it can't see;
  • it's a timing or race condition that only shows up under real load.

A useful middle ground: ask it to explain the relevant code line by line instead of changing it. Understanding the code is often what breaks the loop, for you or for it.

A reusable prompt shape

Most of the prompts above follow the same structure, and it's worth using on purpose:

  1. Role: "You are reviewing a Next.js app for a bug."
  2. Context: stack, files, what changed recently.
  3. Task: one specific thing.
  4. Constraints: what it must not touch or do.
  5. Output: the format you want back (ranked causes, a diff, a test).
  6. Check: how it should verify its answer before giving it to you.

Vague prompts get vague code. A prompt with constraints and a check gives the assistant a way to know when it's wrong.

The short version

  1. Two failed attempts means stop.
  2. Checkpoint with git and read git diff --stat.
  3. Fresh session, with a summary you write.
  4. Diagnosis before code.
  5. Shrink the problem and bound the edit.
  6. Paste raw evidence.
  7. For production-only bugs, check the environment first.

Want the prompts ready to paste?

We collected 50 prompts built on that six-part structure, covering planning, building, debugging, security, UI and selling, into 50 AI Coding Prompts to Plan, Build, Debug, Secure & Sell Software. The debug section covers root-cause-first prompts, "works locally, fails live" and breaking stuck loops. Everything in this post works without it.

If you'd rather have someone build or fix the app for you, see verdanopulence.digital/services.