How Coding Agents Edit Files: Diffs, Snapshots, and Fast Apply Coding agents fail more often at the file-system boundary than at reasoning, according to an analysis of how Aider, Claude Code, Cursor, OMP, DeepSeek Harness, OpenCode, and Morph write code to disk. Aider benchmarks cited in the piece show that forcing models to generate strict unified diffs dropped task completion rates from 59% to 26% on complex files due to line-count arithmetic errors, while search-and-replace blocks use ten times fewer tokens (200–500 versus 4,000–6,000) on files over 400 lines. Production tools rely on four architectures — raw string replacement, line-anchored snapshot hashes, syntax tree codemods, and dedicated neural models running speculative decoding at 10,000 tokens per second. On this page How Coding Agents Edit Files: Diffs, Snapshots, and Fast Apply Applying diffs to disk breaks more agent workflows than reasoning errors. Here is how Aider, Claude Code, Cursor, OMP, DeepSeek Harness, OpenCode, and Morph modify code. Writing code changes to disk breaks more agent workflows than model reasoning errors. A frontier model plans a clean refactor, handles edge cases, and writes working functions. The failure happens at the file system boundary. When an agent harness attempts to modify a 1,200-line file, it hallucinates line offsets, drops unedited closing braces, or corrupts indentation. The user ends up fixing broken syntax by hand. Production coding tools use four distinct architectures to modify files on disk: raw string replacement, line-anchored snapshot hashes, syntax tree codemods, and dedicated neural models running speculative decoding at 10,000 tokens per second. The Arithmetic Blindness Problem Language models do not count lines. Autoregressive transformers predict the next token from statistical distributions. When a tool asks an LLM to generate a standard unified diff the format used by git diff and GNU patch , the model must calculate hunk header integers: @@ -142,18 +142,22 @@ export function verifySession token: string { The numbers -142,18 and +142,22 specify exact line offsets and hunk lengths. If the model miscounts by a single line, standard patch utilities reject the patch. In benchmark tests on Aider https://aider.chat/ , forcing models to generate strict unified diffs caused task completion rates to drop from 59% to 26% on complex files because of line-count arithmetic errors. Unified diff failure points: ───────────────────────────────────────────────────────────── Spatial line arithmetic: Autoregressive models miscount offsets Whitespace sensitivity: Tabs vs spaces break exact string matches Lazy elision hazards: "// rest of code unchanged" deletes files Token and latency overhead: Rewriting 1,500 lines consumes 5,000 tokens ───────────────────────────────────────────────────────────── File modification introduces four failure modes: 1. Lazy Code Truncation: When generating large files or wide diffs, frontier models emit placeholders like // ... existing implementation remains unchanged ... . Writing this output to disk destroys existing code. 2. Whitespace and Indentation Fragility: In Python or YAML, a single tab-versus-space mismatch causes exact string matchers to fail. 3. Token and Latency Overhead: Rewriting a 1,500-line file to change three lines requires generating ~5,000 completion tokens. On frontier models, that takes 15 to 25 seconds and costs ten times more than a localized edit. 4. Stale State and Concurrency Drift: In multi-agent systems, if Worker A modifies a file while Worker B plans an edit against the original version, applying Worker B’s edit overwrites Worker A’s changes. 1. Search-Replace Blocks: The Standard Tooling Approach Most production coding tools use search-and-replace blocks rather than raw diffs. Aider’s Search-Replace Blocks and Anti-Laziness Formatting Paul Gauthier, creator of Aider https://aider.chat/ , designed the diff block format: src/auth.ts <<<< SEARCH export function verifyToken token: string { return jwt.verify token, SECRET ; } ==== export function verifyToken token: string { if token throw new AuthError "Token required" ; return jwt.verify token, SECRET ; REPLACE The model outputs the original block followed by the replacement code. The harness locates the search text in the target file and substitutes the new content. Aider’s benchmarks show clear thresholds across thousands of code edits: - Files under 400 lines: Full-file rewrites produce high single-turn reliability on small models. - Files over 400 lines: Search-and-replace uses ten times fewer tokens 200–500 tokens versus 4,000–6,000 and executes in under one second. - Unified diffs as a laziness countermeasure: Switching GPT-4 Turbo from search-replace to unified diffs dropped placeholder comments from 61% to 20% . Strict hunk syntax increased tool-parsing failures on complex files. Claude Code’s Edit Tool Anthropic’s Claude Code https://claude.ai/code uses a structured str replace tool contract: { "command": "str replace", "path": "src/auth.ts", "old str": "export function verifyToken token: string {\n return jwt.verify token, SECRET ;\n}", "new str": "export function verifyToken token: string {\n if token throw new AuthError \"Token required\" ;\n return jwt.verify token, SECRET ;\n}" } The tool enforces a strict constraint: old str must match one unique location in the target file. If old str matches multiple lines such as a generic return null; , the tool rejects the call and requires the model to provide more surrounding lines for disambiguation. This design avoids line-arithmetic failures and forces the model to read the current file state before writing changes. 2. The 9-Stage Resilient Replacer: OpenCode’s Architecture In real repositories, exact string matching fails 20% to 30% of the time. The model remembers code with two spaces instead of four, omits a newline, or swaps single quotes for double quotes. OpenCode https://opencode.ai/ the terminal AI coding agent by SST addresses this failure mode with a 9-stage fallback matcher . If exact matching fails, the tool relaxes constraints step by step: After applying an edit, OpenCode runs project formatters Prettier, Black, Biome to standardize whitespace on disk before the next turn. It then queries the Language Server Protocol for compiler diagnostics and sends any syntax errors back to the model as tool results. 3. Snapshot Anchors and AST Rewrites: Oh My Pi OMP String replacement leaves a major vulnerability: race conditions and stale edits. If an agent reads a file, spends 20 seconds planning a task, and writes changes while another tool or background process touches that file, string substitution applies to the wrong code context. The Oh My Pi OMP https://github.com/can1357/oh-my-pi harness solves this with Hashline , a line-anchored patch language tied to content snapshots: src/auth.ts A1B2 PUT 45.=48: + if token { + logger.warn "Empty token" ; + throw new AuthError "Missing token" ; + } Hashline enforces three controls: - Snapshot Content Hashing file.ts TAG : Every read annotates the file with a 4-hex snapshot hash. If the disk file changes before the edit arrives, the engine rejects the patch to prevent corruption. - AST Block Openers PUT N : : To modify an entire function, the model specifies PUT 14 : . Tree-sitter resolves the closing delimiter of the syntax block. The model avoids calculating closing line numbers. - AST Structural Codemods ast edit : For repository-wide refactors, OMP uses ast-grep metavariables $NAME , $$$ARGS , out . The harness modifies the abstract syntax tree, ignoring whitespace, comments, and line wrapping. 4. DeepSeek Harness dsh and SWE-bench Evaluation When DeepSeek evaluated DeepSeek-V3 https://github.com/deepseek-ai/DeepSeek-V3 and DeepSeek-R1 https://github.com/deepseek-ai/DeepSeek-R1 on SWE-bench Verified where R1 scored 49.2% , they used DeepSeek Harness https://deepseekharness.dev/ dsh , built on the open-source Cordis micro-kernel. DeepSeek Harness provides two execution modes: DeepSeek-V3 / Coder Tool Flow: Agent calls str replace editor with Base64-persisted segment anchors Multi-chunk diff replacement applies edits inside Docker container Harness synthesizes final unified diff model patch for SWE-bench DeepSeek-R1 Diff-First Flow: Reasoning model outputs chain-of-thought and unified diff in fenced block Harness buffers stream, strips reasoning tokens, and extracts diff Harness applies patch to validation container In benchmark evaluation mode Minimal Mode , DeepSeek isolates model capability by stripping the toolset down to two primitives: persistent bash and str replace editor . For DeepSeek-V3 and DeepSeek-Coder, str replace editor uses a multi-chunk diff replacement algorithm. Edits anchor to exact prior code segments and persist in Base64. Once the agent finishes, the harness calculates the unified diff between the initial repository state and the final disk state to create the model patch . DeepSeek-R1 outputs raw reasoning streams rather than JSON tool calls. The harness prompts R1 to output unified diffs in markdown blocks, extracts the diff text, and applies it to an evaluation container. 5. The Two-Tier Paradigm: Speculative Fast Apply The fastest editing paradigm separates code reasoning from file modification. Tools like Cursor https://cursor.com/blog/instant-apply Instant Apply and Morph Fast Apply https://www.morphllm.com/ allow the reasoning model to emit lazy update snippets like // ... existing code ... . A second model merges the edit into the full file. Cursor’s Instant Apply Cursor’s Instant Apply uses a fine-tuned Llama-3-70B model hosted on Fireworks AI. Instead of generating the whole file token by token at 40 tokens per second, the engine uses speculative decoding. Because 95% of the file remains unchanged during an edit, the inference server treats the original file as a draft token stream. It validates draft tokens in parallel batches, sustaining ~1,000 tokens per second ~3,500–4,000 characters per second . Before modifying files on disk, Cursor applies the patch to a shadow workspace , runs TypeScript and LSP diagnostics, and displays an inline diff to the user. Morph Fast Apply Morph exposes an API endpoint trained specifically for code merging. On benchmark runs across real-world repositories: - Standard str replace : 86% accuracy with an average run time of 35 seconds per file due to error recovery turns. - Morph Fast Apply morph-v3-fast : 98% accuracy in 6 seconds per file, sustaining throughput up to 10,500+ tokens per second on custom CUDA kernels. Architectural Comparison | System | Edit Representation | Merge Engine | Lazy Code Handling | Concurrency Guard | Verification Loop | |---|---|---|---|---|---| | Claude Code | str replace JSON tool | Exact substring match | Rejects call | File check before write | User diff prompt + linter | | Aider | diff SEARCH/REPLACE | Regex block search | Rejects placeholder text | Git commit history | Test suite on commit | | OpenCode | edit + apply patch | 9-Stage fallback replacer | Multi-file diff patch | Unique substring rule | Prettier/Black + LSP diagnostics | | Oh My Pi OMP | Hashline + ast edit | Snapshot hash + ast-grep | AST block resolver PUT N : | Snapshot Hash Tag TAG | In-process LSP diagnostics | | DeepSeek Harness | str replace editor / Diff | Multi-chunk diff replacement | Rejects edit | Docker sandbox boundaries | Persistent bash test runner | | Cursor | Speculative Rewrite | 70B Llama-3 Fast Apply | Expands lazy markers | Working tree diff check | Shadow workspace LSP check | | Morph |