← all writing
09 · 03 Sept 2026 · 6 MIN READ

Fault Localization Lost to Just Trying Again

Most mornings the arxiv cs.SE list is a wall of new benchmarks. Today something different stopped me: a paper that runs an actual placebo arm. Not an ablation — a placebo. Repair the wrong span, same length, same budget, and see whether knowing where the bug is beats editing somewhere, anywhere. That design is rare enough in this literature that I read the whole thing. The thesis of this post: the targeted-repair intuition most of us build our loops around does not survive a matched-budget comparison.

What it does

Does Fault Localization Beat a Fresh Attempt? A Placebo-Controlled Study of Test-Guided Code Repair, posted September 1 by Anik Jha, takes a code candidate that failed its tests and gives it three different second chances. Arm one: blind whole-solution resampling — throw the candidate away, generate again, don't look at the failure. Arm two: spectrum-based fault localization to find the suspect statements, then infill that span. Arm three, the interesting one: infill a disjoint random span of the same length. That third arm is the placebo. Prior work almost always compares localized repair against no repair, which quietly confounds three separate explanations for why it works — the failing test carried real information, the edit was small and therefore easy, or the model simply got another sample. Three arms pull those apart.

The setup is three frozen 26–32B models across three benchmarks and 488 failing candidates, plus a separately declared 24B fourth model from a third family held back for replication. What I appreciated more than the setup was the analysis discipline: a pre-declared primary analysis (the paper refers to "the analysis our shipped plan designates primary"), Holm correction across models, and a fourth family committed to in advance rather than added once the numbers looked good. This is a paper that reports a weaker result than its own headline would have allowed it to claim.

The key result

Localization loses. Before any repair even happens, the availability number is brutal: only 9.0% of failing candidates expose a failing public test with a usable spectrum — the precondition for the entire technique holds one time in eleven. Among the 177 candidates that were localizable from a strong suite, localized infilling went head-to-head with blind resampling at a matched attempt count and won 3, lost 40 (p = 3.0 × 10⁻⁹), the opposite of the paper's own hypothesis. It replicates in the held-out third family at −11.3 points (95% CI [−16.6, −6.8]), and widening the edit window does not rescue it. Repricing attempts as tokens narrows the gap without overturning it: a span attempt spends 21.7 generated tokens against 371.1 for a full resample, yet 16 localized attempts reach 6.8% while one blind attempt already reaches 10.1%. The mechanism is right there in the diagnostics — infilling reproduces the removed span verbatim in 48.9% of attempts. You cut the hole and the model sews it back exactly as it was, which is why more budget buys nothing.

Why it matters

The 9.0% is the number I'd put on a whiteboard. Nearly every test-guided repair architecture I've built or read assumes a failing test with a clean spectrum is the normal case, and it treats localization as the cheap part before the expensive part. In the population you actually operate on, that signal is missing 91% of the time, which means the honest question about a repair loop is not "is my localizer good?" but "what fraction of my failures even reach the localizer?" If you run a Claude Code sub-agent pipeline shaped like run the tests → identify the failing line → dispatch a focused patcher, two of those three steps are conditional on evidence that usually isn't there, and the fallback path — whatever happens in the other 91% — is doing most of the real work while getting none of the engineering attention. Instrument the precondition hit rate before you tune the mechanism.

The second half is the 48.9% verbatim-reproduction figure, and it generalizes past this paper's small models. Constraining a model to fill a hole in code it just wrote anchors it to what it just wrote; the surrounding context is a very strong prior for the thing you're trying to change. That's the same failure mode as handing an agent a diff and saying "fix only these lines" — you've made the edit cheap and also made it likely to be the same edit. Concretely, two things I'd change. First, budget allocation: prefer independent resamples with fresh context over repeated attempts at the same narrow span, because varied attempts explore and narrow attempts converge on what already failed. Second, if you keep localization, use it as a selection signal — which candidate to discard, which test to prioritize, which file to route to a specialist — rather than a generation constraint on which characters get regenerated. The information is real; the mistake is spending it on shrinking the edit surface.

The caveats

The takeaway

What I'm filing away is less the finding than the shape of the experiment. When you add a mechanism to an agent loop — retrieval, localization, a critic, a planning step — and it improves the numbers, you have not yet learned that the mechanism's information is what helped. You may have learned that a second call helps, or that a smaller edit helps. The cheapest way to find out is to build the dumb version that has the same shape and none of the signal, and run it as a third arm. I'm adding a placebo arm to the next eval I write for a retrieval step I've been assuming earns its keep, and I expect to be a little annoyed by the answer.


Paper: arXiv:2609.00854 — Anik Jha, September 1, 2026 (cs.SE, cs.AI, cs.LG).


Working on something similar?

Say hello — I read every email.