AnthropicClaude Certified Architect – Foundations2026-102.5 Select and apply built-in tools (Read, Write, Edit, Bash, Grep, Glob) effectively
Recover ambiguous edits without widening intent
Completed by the knowledge check
Learning objective
Recover from non-unique Edit anchors by reading the relevant file and choosing a safe whole-file replacement when needed.
Core idea
An ambiguous Edit is a signal that the proposed text does not identify the intended location. It is not permission to broaden the requested change. If one statement appears in four functions and only one function should change, replacing every occurrence makes the edit executable by changing the requirement.
For a code generation agent, recovery starts with Read on the relevant file. Fresh content lets you choose a longer unique anchor, verify that a global replacement is genuinely intended, or prepare the complete corrected file for Write. Whole-file replacement removes the matching ambiguity, but transfers responsibility to preserving every untouched part of the file. Choose it only when you have enough evidence to do that.
How it works
Interpret the failed match
Edit receives file_path, old_string, and new_string. Its replacement is exact: it does not use regex or fuzzy matching. For a targeted replacement, old_string must occur once. When it occurs more than once, Claude can add surrounding context to select one occurrence or set replace_all: true to replace them all.
Those are distinct intentions. A repeated logging statement inside refund, fee, and correction handlers is ambiguous if the request names only the refund handler. A shared spelling mistake that must be corrected everywhere can justify replace_all: true. The count of occurrences alone does not tell you which intention is correct.
A non-unique match also differs from a missing match. An extra indentation character can make old_string fail to match at all. Repeating the same call repairs neither failure. Read the file to identify whether the problem is repeated text, stale text, or an inaccurate copy, then construct a call that matches observed content.
Prefer a unique anchor when practical
Use Read.file_path to inspect the target function and enough neighboring content to disambiguate it. Copy the anchor exactly, including whitespace. A function declaration plus the nearby statement may uniquely identify the edit where the statement alone does not.
The longer anchor changes the matching scope, not the intended behavioral scope. Its new_string must retain the surrounding text and modify only the requested part. Otherwise, making the anchor unique can introduce unrelated changes just as a whole-file rewrite can. Choose the smallest observed passage that identifies the correct occurrence clearly.
Do not use replace_all: true merely because uniqueness failed. That field is appropriate only when every occurrence should receive the same replacement. It is not a “force this one edit” switch and does not select an occurrence by its function’s meaning.
Use complete replacement when needed
The exam guide explicitly names Read followed by Write as the fallback when Edit cannot find unique anchor text. The product’s Write semantics explain the trade-off: Write.content replaces the entire file without matching an anchor, appending, or merging.
For this fallback, read the complete file, identify the intended change in that content, and supply the complete corrected content with the same file_path. Preserve imports, declarations, comments, and every unrelated branch. There is no implicit instruction in Write to keep whatever you omitted.
Check whether the read actually completed. A PARTIAL view is not a complete source snapshot. Use Read.offset and Read.limit to obtain the remaining content as documented in 2.5.2 before constructing a replacement. A few matching lines from Grep are enough to locate the handler, but not enough to reproduce the entire file safely.
Read the relevant file again if intervening changes invalidate the content used to construct the replacement. The tools reference allows some exact edits against changed files, but a complete replacement must account for the entire intended final content. A successful Write is not proof that the replacement retained changes outside the target statement.
After mutation, inspect the affected content with Read and inspect the patch with Bash running git diff for that file. Run the repository’s relevant verification command through Bash. Anthropic’s best practices recommend giving Claude concrete verification criteria; here those criteria include both the requested handler change and preservation of the handlers that must remain unchanged. Every recovery starts with a fresh read and ends with the same checks.
Key distinctions and trade-offs
The recovery choices differ in what they require:
| Choice | Appropriate condition | Main preservation burden |
|---|---|---|
Longer old_string | Surrounding text uniquely identifies the intended occurrence | Reproduce the selected surrounding text exactly |
replace_all: true | Every matching occurrence should change identically | Verify that the scope really includes every occurrence |
Read then Write | Targeted matching is unsuitable and complete corrected content is available | Preserve the entire file outside the intended change |
Matching safety versus behavioral correctness: A unique anchor prevents ambiguity about which text is replaced. It does not prove that changing that text is the right implementation. Conversely, avoiding matching with Write does not prove that the whole replacement is correct.
Less returned content versus complete preservation: A targeted read can support a precise Edit. Whole-file replacement needs whole-file evidence. Choosing the fallback after reading only the target lines saves context by discarding the information required to preserve the rest.
Recovery versus bypass: A shell replacement through Bash is not a repair for an unresolved target. It still needs a rule that selects the intended occurrence. Dedicated file operations make that intent explicit; their operation-level trade-offs are covered in 2.5.2.
Architecture / decision scenario
A Claude Code agent must add reasonCode to the refund handler’s log payload. Four adjustment handlers contain logger.info("adjustment posted", { orderId });. An Edit with that statement as old_string fails because the anchor is not unique.
The agent uses Read on the adjustment module and identifies all four occurrences. For a small refund function with distinctive surrounding lines, it can retry with a longer unique old_string. It retains those surrounding lines in new_string, adding reasonCode only in the refund payload. Setting replace_all: true would also alter fee and correction logging, so that option fails the requirement.
If a sufficiently unique anchor would require reproducing most of the module and make the targeted replacement difficult to review, the agent can choose the whole-file fallback instead. Its first read is partial, so it retrieves the remaining content before supplying Write.content. The corrected file changes only the refund payload and preserves the other three handlers and their payloads.
Finally, git diff shows one intended refund change and no modifications to the other handlers. The agent runs the relevant tests and reads the resulting refund branch. The recovery is complete because the required change and preservation conditions are verified, not merely because a tool call succeeded.
Common exam traps
- Retrying an unchanged ambiguous
old_stringand expecting a different selection. - Treating
replace_all: trueas a way to force a single-occurrence change. - Supplying the changed function alone as
Write.contentfor a multi-function file. - Reconstructing a whole file from a partial read or search excerpt.
- Widening an anchor while accidentally changing its surrounding code.
- Treating a successful replacement as proof that unrelated content survived.
Where the exam guide differs
The exam guide assesses Read of the full file followed by Write when Edit fails on non-unique anchor text. For an item framed around that failure, select the full-file Read + Write recovery; retrying the unchanged anchor and using replace_all: true when only one occurrence should change are distractors.
The product’s Edit documentation instead names a longer old_string with surrounding context or replace_all: true as its non-uniqueness remedies. The latter fits only an intended global change. Whole-file replacement is supported by Write’s semantics, but is not listed there as an Edit remedy. Recognize the guide’s assessed fallback while using the precise recovery that preserves the actual task’s scope.
What to remember
Read after an ambiguous edit, then match the recovery to the intended scope. Use a unique anchor for one occurrence and replace_all: true only for an actual global change. Use Read plus Write when complete replacement is needed and complete content is available; verify both the change and the preserved code.
Knowledge check
An agent must add reasonCode to the refund handler’s log payload. Four handlers in the module end with logger.info("adjustment posted", { orderId });, so an Edit with that line as old_string fails as not unique. The refund handler is short, and its signature two lines above the statement appears nowhere else. What should the agent do?
old_string to just the log message and retry the Editreplace_all: true on the same Edit and run it againsed substitution through Bash on the logging statementEdit with the refund signature in old_stringEdit needs an exact, unique anchor; shortening a repeated statement does not distinguish its occurrences. Include the refund signature and the intervening lines in old_string , then retain those surrounding lines in new_string while changing only the payload. replace_all and a substitution matching the repeated statement would change all four handlers.In another module, the four handlers are identical for dozens of lines around the repeated log statement, so a unique old_string would span most of the file. The agent chooses whole-file replacement to change only the refund handler’s payload. Which operation preserves the requested scope?
replace_all: true , then restore the other three handlers one by oneWrite the complete corrected file content backWrite that handler alone as the contentWrite their bodies as the file contentWrite matches nothing, so the ambiguity disappears, but it replaces the whole file: the corrected content must carry every import and all four handlers. Supplying only the refund handler would delete the rest of the module. Replacing all four occurrences and undoing three is a change of scope followed by repair, not a recovery.A user-facing message misspells “Received” as "Recieved" in six places in one file, and every occurrence must be corrected. The agent’s Edit fails because old_string is not unique. It should fix all six with the fewest tool calls and without reproducing unchanged code. What should it do?
Write it back with all six correctionsEdit calls, each with a longer unique old_stringEdit with replace_all: true for the misspelled stringEdit with the same old_string and the same new_stringreplace_all: true is the documented remedy when every occurrence should receive the same replacement, which is the case here. It is wrong only when some occurrences must stay. Six widened anchors would work but take six calls, and a Write makes the agent reproduce the whole file to change one word.Before editing, git diff showed no changes for this module, and no other process changed it. The agent used Read and then Write to change the refund handler’s payload in a module with four handlers. Write reported success. Which evidence best shows that the other three handlers survived unchanged?
Write returned for the file pathGrep count showing four occurrences of "adjustment posted" in the fileRead of the refund handler’s lines in the modulegit diff of the file through Bash showing one changed payloadWrite proves the file was written, not that it preserved unrelated content. With no pre-existing diff or intervening changes, a file diff showing only the intended payload change verifies preservation against the pre-edit baseline. Four matching log lines say nothing about the rest of each handler, and re-reading the refund lines checks only the change.References
- Anthropic, Tools reference
- Anthropic, Agent SDK Python reference
- Anthropic, Best practices for Claude Code
- Anthropic, Claude Certified Architect – Foundations Exam Guide