Worktree isolation broken: edits land on main checkout when paths resolve to repo root
Type
Bug
Summary
A session started with -w <name> (worktree) silently applied nearly all file edits to the main checkout (on master) instead of the worktree branch, even though the session's cwd and gitBranch both correctly reported the worktree the whole time. The worktree branch ended up almost empty; all real work landed on master. No warning was raised.
What I observed (from the session transcript)
- Every transcript entry reports
cwd = <repo>/.claude/worktrees/<name>andgitBranch = worktree-<name>— so the harness believed it was operating in the worktree. - Yet of ~70
Edit/Writecalls, all but one used absolutefile_paths under the main checkout (<repo>/packages/...), not under the worktree (<repo>/.claude/worktrees/<name>/packages/...). - Net effect: the feature work was committed on
master; the worktree branch was effectively unused.
Root cause
The model worked from file references that were repo-root-relative (e.g. from an auto-memory/notes file listing packages/rrweb/src/record/foo.ts). When converting those relative references to absolute paths, the model anchored them to the canonical repo root (<repo>/packages/...) rather than the worktree root (<repo>/.claude/worktrees/<name>/packages/...).
Because the worktree lives inside the repo at .claude/worktrees/<name>, an absolute path into <repo>/packages/... is a perfectly valid, existing file — just the wrong copy. Reads and edits succeeded silently against the main checkout, defeating worktree isolation entirely.
Why this is dangerous
- The
cwd/gitBranchsignals say "worktree," giving false confidence that work is isolated. - The whole point of
-wis isolation, but absolute paths to the parent repo are not guarded. - The user only discovers the mistake later, when changes show up on
masterinstead of the worktree branch.
Suggested fixes (any of)
- When a session is bound to a worktree, treat the worktree root as the canonical project root for resolving relative paths — so
packages/...resolves inside the worktree. - Guard/warn (or block + confirm) when an
Edit/Writetargets a path inside the parent repo's working tree but outside the active worktree, while a worktree session is active. - Surface the worktree root prominently in context so the model anchors relative paths there.
Environment
- Claude Code v2.1.81
- Linux
- Worktree created via
claude -w <name>, stored at<repo>/.claude/worktrees/<name>
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗