[BUG] Edit tool writes to a sibling worktree's copy of a file (silent), instead of the cwd worktree, when both checkouts have the same tracked path
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Summary
When Claude Code's session cwd is inside a git worktree, calling the Edit tool on a tracked file whose path also exists in the primary checkout can silently land the change in the primary checkout's copy of the file, not the worktree's copy.
The Edit tool reports success, and subsequent Read calls return the edited content (so from Claude's perspective the change "took"). But git status / md5 / grep / scp from the worktree all see the file unmodified. Meanwhile, git status in the primary checkout shows it dirty with exactly the edit that was intended for the worktree.
This is particularly nasty in repos with many parallel worktrees — edits intended for the branch you're on can land on main directly, with no warning.
Environment
- Claude Code version: 2.1.98
- Platform: macOS (Darwin 25.3.0), zsh
- Repo setup:
- Primary checkout:
/Users/<me>/dev/<repo>onmain - Worktree:
/Users/<me>/dev/<repo>/.claude/worktrees/<slug>on a feature branch - Both have the same tracked file
public/admin.php(different inodes — not hardlinked). - ~50 worktrees on this repo. Session cwd was the worktree.
What I observed
- From inside the worktree, I called
Editonpublic/admin.php(relative path) to add aconsole.log+try/catchdebug wrapper. Tool returned "updated successfully". - Subsequent
Readof the same path returned the edited content. - From
Bash(same worktree cwd):
md5 -q public/admin.php→ original hash, unchangedgrep -c '\[tcdbg\]' public/admin.php→ 0git status -s public/admin.php→ clean
git statusin the primary checkout showedM public/admin.php.git diffthere showed exactly the edits I had intended for the worktree.scp public/admin.php …from the worktree pushed the unmodified file to staging, leading to a long debugging detour where I couldn't figure out why my debug output never showed up.
Workaround
Falling back to perl -i -0777 -pe '…' via Bash worked correctly — the change landed in the worktree as expected and git diff saw it. That's how I shipped the actual fix in the end.
Clean repro attempted (did NOT reproduce)
- Created
edit-tool-bug-test.txtonly in the worktree (no copy in the primary checkout). - Edited it via
Editwith both absolute and relative paths. - Both edits landed in the worktree correctly. No leak to the primary checkout.
So the trigger seems to require the same tracked path to exist in both checkouts. My guess is Edit is resolving the path through some shared git index / inode cache that maps to the primary worktree's copy instead of the cwd worktree's, but I can't confirm that from the outside.
Inode check (to rule out hardlinks)
/Users/<me>/dev/<repo>/public/admin.php → inode 15522943, links 1
/Users/<me>/dev/<repo>/.claude/worktrees/<slug>/public/admin.php → inode 15522642, links 1
Different inodes — the two files are independent copies, as expected for git worktrees.
Why this matters
- Silent failure. Tool says success,
Readconfirms — but every downstream tool (git,md5,grep,scp, build pipelines) sees the unmodified file. - Wrong-branch commits. Edits intended for a feature branch can land directly on
mainif you also happen to be running another Claude Code session there or if your tooling auto-stages. - Hard to notice. The bug only surfaces when you reach for a non-Claude tool to verify, or when you try to merge / push and git complains about uncommitted changes you didn't make.
Asks
- Make
Edit's path resolution honor the current session's worktree, not the primary checkout, when both contain the path. - At minimum, after a successful
Edit, surface a warning when the file Claude believes it wrote has a different on-disk hash than expected — i.e. a post-write verification step.
What Should Happen?
See Bug Post
Error Messages/Logs
Steps to Reproduce
See Bug Post
Claude Model
None
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.98
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
_No response_
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗