Skip to content
Coding AgentsEdit formats

Senior · Core path · 7 chapters

Edit formats

Whole-file rewrite vs unified diff vs search-and-replace blocks, and their very different failure rates

Choosing an edit format from intuition causes malformed patches, silent overwrites, and expensive retries in production coding agents.

Read these first

What you will know

  • Compare whole-file rewrite, unified diff, and search-replace on the same task

    Use identical prompts and fixtures, then record validity, unintended-change, token, and latency outcomes for each method.

  • Measure the failure rate of each format on a representative task set

    A useful rate needs a defined denominator and failure taxonomy, because a patch that applies but changes the wrong code is still a failure.

  • Explain why diffs fail on line numbers and rewrites fail on length

    Context drift invalidates anchors, while output limits and truncation can turn a complete replacement into a partial or corrupted file.

  • Choose a format for a given model and defend it

    The decision should weigh model context and tool behavior against change size, verifier strength, retry cost, and the consequences of an incorrect edit.

  • Recover from a malformed edit

    Safe recovery requires detecting corruption, restoring a known-good version, and retrying without compounding changes or losing unrelated user work.


Chapters

  1. 1

    A unified diff asks for arithmetic the model cannot check

    Multi-hunk patches succeed about four times in five, the failures are always the later hunks, and the first hunk is essentially never the problem. Every hunk header after the first states a line number computed against the pre-patch file, while each applied hunk shifts everything below it. The model is doing arithmetic it has no way to verify, and the drift compounds down the file.

  2. 2

    A whole-file rewrite ends at the output cap in silence

    Set the agent to whole-file rewrite and a 1,400-line module comes back ending mid-function, with no error anywhere in the loop: the output hit the token limit and the tail was dropped. Do the arithmetic first — 3,000 lines is roughly 30k to 40k tokens against an 8k cap, so the file is destroyed rather than edited. A format that cannot apply incorrectly is useless if it cannot be emitted.

  3. 3

    A search block is an anchor that must match byte for byte

    Search-and-replace blocks cut apply failures sharply and add two new categories: search text that "is not present" when a human can plainly see it, and an edit that applies cleanly in the wrong place. The model reconstructs the anchor from what it read rather than copying it, so a tab becomes spaces and the byte match fails on text that looks identical. Short anchors have the opposite problem — several matches, and the applier silently takes the first.

  4. 4

    A unique anchor is the cheapest guard against a wrong-place edit

    Both of the previous chapter's failure modes have short mitigations. Require the search block to be unique in the file and refuse on more than one match instead of silently taking the first: counting the matches before applying is the cheapest check that catches an edit about to land in the wrong place, and confirming the matched region sits inside the symbol the task named catches the rest. For the false rejections, give the model the exact bytes it must quote back verbatim rather than reconstruct from memory, and decide deliberately whether to normalise whitespace on match — that switch trades one failure mode for the other rather than removing either.

  5. 5

    Apply rate is not a failure rate

    A comparison reporting 91% clean applies for unified diff against 99.5% for whole-file rewrite does not show rewrites are more reliable. A rewrite that lands intact while silently dropping a function, reordering imports or reverting an unrelated line applied perfectly and is still a defect. Build the taxonomy and the denominator instead, on fixed fixtures rather than production traffic, whose tasks were routed to the format that already suited them. Run all three formats over identical prompts and record four outcomes per attempt — validity, unintended change, tokens, and wall-clock latency, since rewrite output is generated serially and a 3,000-line file costs minutes per attempt where a search-replace block costs seconds.

  6. 6

    Choose the format from the cap, the change size and the verifier

    For a legacy Java service with 2,000-line files, surgical edits, an 8k output cap and a strong suite, search-and-replace wins: output scales with the size of the change, and the suite covers the format's weakness by failing an edit that lands in the wrong place. Format is a property of model, repository and task together, which is why standardising on what the frontier model handles concentrates failures on the small local one.

  7. 7

    Restore from the snapshot before retrying a broken edit

    An edit that leaves a source file unparseable halfway through a run has one correct first move: restore the pre-edit snapshot, then retry. Anything else compounds — a second patch written against corrupted text, or a repository-wide checkout that discards an engineer's unrelated uncommitted work. Covers detecting the corruption before the loop wastes an iteration on it, and keeping the retry from stacking on a partially applied change.

External resources