[BUG] Edit tool silently misses some Edits in a rapid Edit + git mv + commit sequence (selective miss within same commit; refuted hypothesis 2 vs 1+3 still open)
What's Wrong?
Edit tool calls during a long agent flow (Edit + git mv + git add + commit, in rapid succession on tracked markdown files) returned "The file ... has been updated successfully." and Read showed the new content, but the committed content (verified via git show <SHA>:<path>) did NOT contain the Edits.
The pattern is selective, not whole-file:
- Some Edits in the same close-succession sequence landed (a slice plan table, a
## Fix Releasedsection, one investigation-task tick) - Other Edits in the same sequence did NOT land (Status field change, Priority line parenthetical removal, Effort wording update)
All Edits returned the same success acknowledgement; only git show revealed the misses.
What Should Happen?
- Edit modifies the file on disk such that subsequent
git add+ commit ships the modified content - If Edit cannot complete (e.g., buffered state would be lost by a follow-on
git mv), the tool surfaces an error rather than silently producing partial content - The selective-miss shape is the load-bearing signal: ANY hypothesis on the failure mode must explain how some Edits in a tight sequence land while others don't
Error Messages/Logs
NONE — Edit returned success on every call; Read after Edit confirmed the new content; only `git show <SHA>:<path>` after commit revealed that some Edits were missing from the tree.
Steps to Reproduce
The original failure mode was observed in production work on 2026-05-17. A controlled 7-test reproduction matrix run on 2026-05-18 (against /tmp/p011-repro.md with Claude Code 2.1.143) refuted the simplest hypothesis (Edit silent no-op on old_string mismatch) — every mismatch variant returned a loud, structured error:
| # | Variant | Result |
|---|---------|--------|
| 1 | Exact match (control) | Applied; success |
| 2 | old_string has trailing space file does not | "String to replace not found in file." |
| 3 | old_string has leading space file does not | "String to replace not found in file." |
| 4 | old_string entirely absent from file | "String to replace not found in file." |
| 5 | Case mismatch | "String to replace not found in file." |
| 6 | Non-unique old_string (2 matches) | "Found N matches… replace_all is false." |
| 7 | new_string == old_string (semantic no-op) | "No changes to make: old_string and new_string are exactly the same." |
So under isolated Edit-only conditions, the contract is honored. The unverified hypotheses are:
git mv+ Edit buffer-flush interaction — Edit modifies an in-memory buffer; subsequentgit mvof the same path reads the on-disk state before the buffer flushes. (Tested only partially; selectivity-of-loss within the same commit doesn't fully fit this model.)- Read-before-Edit staleness under concurrent process touch — between Read and Edit, some other process touched the file, and Edit applied against the stale snapshot. (Hard to instrument from the adopter side.)
A full reproduction would require: rapid Edit + git mv + git add + commit sequence on a tracked file inside a real repo, then git show <SHA>:<path> verification. Not run in iter 11 because there is no pre-existing regression to anchor it.
Affected Surface
Claude Code CLI, version 2.1.143 at iter 11 measurement time. Original P005 slice 2-4 work that surfaced the bug ran ~2026-05-17 on whatever Claude Code version was current then; not directly identifiable from session traces.
Evidence
- Commit
80a8cb0(2026-05-17, P005 slice 2-4 closure on downstream voder-mcp-hub): Edits to set Status: Verification Pending, remove the deferred-re-rate parenthetical, update the Effort wording, and tick investigation tasks did not all land. Verified viagit show 80a8cb0:docs/problems/005-mcp-oauth-needed-for-claude-ai-web-and-ios.verifying.md— Status field still "Known Error"; deferred parenthetical still present; Effort wording was pre-slice "slice 1 of ~4" not post-slice "all 4 slices shipped"; investigation tasks unticked. The slice plan table and the entire## Fix Releasedsection DID land — selective miss within the same commit. - Commit
2d54d66(same session, README-history closure): Edit added a closure fragment that did not land — committed file had 4 fragments, not the 5 intended.
Both detected by incidental re-read during follow-up work.
Versions
- Local plugin: not applicable (this is a Claude Code CLI tool report, not a plugin)
- Upstream package:
@anthropic-ai/claude-code@2.1.143 - Claude Code CLI:
2.1.143 (Claude Code) - Node:
v22.17.1 - OS:
Darwin 25.3.0 x86_64
Related Issues
- #53940 — Cowork Edit/Write tools silently truncate files via byte-conservation buffer cap (deterministic, fires at all file sizes). Different product (Cowork desktop research preview) and different mechanism (byte-conservation truncation, post-edit byte count == pre-edit byte count) but the same class of failure — Edit returns success while not writing the intended content. Triage may want to consider whether the two surfaces share an underlying buffer-management layer.
Cross-reference
Reported from voder-mcp-hub (downstream project):
- Local P011:
docs/problems/known-error/011-edit-tool-edits-silently-regressed-during-slice-2-4.md
Tracked locally as P011 in the downstream project's docs/problems/ directory.
Preflight Checklist
- [x] I have searched existing issues; #53940 surfaces a related-but-distinct bug (different product, different mechanism) noted in Related Issues above
- [x] This is a single bug report
- [x] I am using the latest version of Claude Code (2.1.143)
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗