toolcall() ← all concepts

// concept · agentic coding

Your agent doesn't retype the file.

It finds one exact chunk of text and swaps it. Understanding that one mechanism explains most of what goes wrong — and why "refactor this module" fails where "rename this function" succeeds.

// the mechanism

The dominant edit tool is a string replacement: the agent supplies the exact text to find and the exact text to put in its place. The match must be unique — zero matches is an error, and so is more than one.

# roughly what the tool call looks like old_str: "def parse(self, raw):" new_str: "def parse(self, raw, strict=False):"

That uniqueness requirement is a safety feature, not a limitation. An edit that could land in two places is an edit that could silently corrupt the wrong one, so the tool refuses rather than guesses. It also explains the read-before-edit flow you see in transcripts: the agent has to see the current bytes to write an anchor that matches them.

Why scope is the whole game

Benchmarks are blunt about this. On SWE-bench Goes Live, a single-file patch under five lines was solved around 48% of the time. At three or more files, or 100+ lines, the solve rate falls below 10% — and seven-file changes are essentially never solved. Fixes that landed were about 8× smaller than fixes that didn't (median 12.5 lines vs 104.5).

1 file, <5 lines ~48% solved medium change falls off fast 3+ files / 100+ ln <10% solved

Anthropic's own guidance puts it plainly: if you don't define scope, the model will — and big multi-file rewrites are where quality collapses.

Size is partly a proxy, not purely a cause. Bigger changes also tend to be harder changes needing more cross-file reasoning, so some of this correlation is about difficulty rather than edit size alone. The practical advice survives either way: the narrower your ask, the better your odds.

What breaks on a whole-file rewrite

When a model regenerates an entire file instead of patching it, three failure modes show up that targeted edits simply cannot produce:

Silent collateral damage. Unrelated code gets dropped, restyled, or stripped of comments under output-length pressure — changes you never asked for, in code you never mentioned.

Truncation. A long file can exceed the output cap mid-rewrite and come back cut off. You pay for every line either way, and output is the expensive direction — see why the reply costs ~5× the prompt.

Laziness. The famous // ... rest of the code here ... elision. It was measured: one model went lazy on 12 of 89 tasks with search/replace and 4 of 89 with unified diffs, and the pass rate moved from 20% to 61% with the stricter format.

The rule

ask for one function, one file, one behaviour not "clean up this module"

Name the file. Name the function. Describe one behaviour change. If the work is genuinely large, split it into a sequence of small edits rather than one broad instruction — you keep the blast radius bounded and each step verifiable.

Targeted editing isn't universally "more correct". For weaker models, and for files under roughly 400 lines, whole-file output can actually outperform diffs. Targeted edits win on cost, latency, truncation-avoidance, anti-laziness, and bounded blast radius — which is why the agents you use default to them.

Sources: SWE-bench Goes Live · Claude Code best practices · text editor tool · Aider — unified diffs & laziness

One concept a week. Free.

The deeper, copy-paste version of each ToolCall short — in your inbox.

// total: 0.00 · spam: void · unsubscribe: one click