An LLM asked to find a bug will always find one
If you run an LLM bug-fixer in a loop until it says the code is clean, you should expect it to break working code faster than it repairs broken code. That is the uncomfortable headline of If It's Not Buggy, Don't Fix It by Wang-Lin, Isopoussu and Mahon (Warwick / UnlikelyAI). The models they tested are small, and I will get to why that matters. The loop design they tested is not small at all. It is the default shape of most autonomous review-and-repair harnesses.
The setup
Take a single C++ file from a competitive programming dataset, where hidden test cases tell you for certain whether it is correct. Ask the model to find and fix the most important bug. Apply the fix. Feed the result back in, with no memory of previous rounds. Repeat up to 100 times, or until the model decides there is nothing left to fix.
No history is a deliberate choice, and a realistic one. It is what you get when a human approves changes without reading them, when past states would overflow the context window, or when one agent hands work to another.
The numbers
The authors measure two per-step rates: how often a broken file becomes correct (repair) and how often a correct file becomes broken (damage).
With atomic search/replace edits and greedy decoding, Gemini 2.5 Flash-Lite started from correct code and damaged it on 29% of steps, while repairing only about 6%. Qwen2.5-7B was worse: 42% damage per step. Starting from broken code did not rescue things. Flash-Lite's repair rate on genuinely buggy files was around 2% per step with atomic edits, against 26% damage.
Whole-file rewrites were far gentler. Flash-Lite's damage rate on correct code fell to about 17%, and on buggy code it actually repaired more than it damaged (10% vs 7%). That is the one configuration where the loop is net positive, and it is still close.
Two more findings are worth keeping. First, the models consistently claim to find bugs in bug-free programs, because the prompt told them there is one to find. Second, long runs often settle into cycles: the same change added, removed, and added again, indefinitely. The loop does not converge on correct code. It converges on a rut.
The mechanistic bit
The authors probe the model's activations and find a direction that behaves like an internal "this code is buggy" signal. It fires on real bugs and on imagined ones, and steering along it changes how eager the model is to edit. Treat this as suggestive rather than settled, since it is shown on one open model. But it fits the behavioural result neatly: the prompt switches the "buggy" representation on, and nothing in the loop ever switches it off.
Where it is narrower than it sounds
The models are a lightweight Flash-Lite tier and a 7B open model from 2024. Frontier models are almost certainly better at saying "this is fine." The test files are short (a median of about 40 lines), single-file, and algorithmic. And critically, the loop never runs the tests. The model is judging correctness by reading alone.
So this is not evidence that current coding agents wreck your repo. It is evidence about a specific failure shape, and that shape is the useful part.
What it means if you build these loops
A loop whose only stopping condition is the model's own verdict has no stopping condition. The model was asked to find a bug, so it finds one. More capable models push the false-positive rate down. They do not remove the structural problem.
Put an external oracle in the loop. Tests, a type checker, a reproduction case. The paper's worst numbers come from a setup with no ground truth anywhere in the cycle. If a proposed fix does not turn a failing check into a passing one, it should not be applied.
Allow "no change" as a first-class answer. Prompts that say "fix the most important bug" presuppose a bug. Ask whether there is one first, and make an empty answer cheap and acceptable.
Carry history. Cycling happens because the model cannot see that it already tried and reverted this exact change. Even a short log of prior edits breaks the loop.
Prefer bigger edit units for repair. The gap between atomic edits and whole-file rewrites was large and consistent. Small patches invite the model to keep finding one more small thing.
Cap iterations and treat hitting the cap as a failure signal, not a finish line.
The title is the right advice. The harder engineering problem, which the paper names but does not solve, is teaching the harness when to stop asking.
Source: Xietao Wang-Lin, Anton Isopoussu, Louis Mahon, "If It's Not Buggy, Don't Fix It: On the Dynamics of Iterative Bug-fixing with LLMs", arXiv:2609.10123, September 2026.
Source: https://arxiv.org/abs/2609.10123
Stay in the loop
One dispatch per week — what I shipped, what broke, and what I learned from the field. No filler.
What should I write about?
Got a topic you'd like me to cover? I read every suggestion.