EnterWorktree intermittently moves the working directory but not the session root

Status Open
Reported on v2.1.220
Maintainer reply None cached
Activity 0 comments · opened Aug 12, 2026

Summary

EnterWorktree appears to apply only partially on some invocations: file operations relocate into the new worktree, but the session itself stays rooted at the original directory. The call returns its normal success message in both cases, and pwd reports the new worktree path in both cases, so from inside the session the two outcomes are indistinguishable.

I have 13 runs where every input I control was identical and the outcome split 9/4.

Environment

  • Claude Code 2.1.220
  • macOS 26.5.2 (Apple silicon)
  • Sessions launched non-interactively into Terminal via osascript, with --permission-mode dontAsk --settings <profile>.json and a slash command as the initial prompt
  • Target: a linked git worktree under <repo>/.claude/worktrees/<name>

What I observed

Across 13 automated runs, each launched by an identical script and each executing the same skill:

  • every run called EnterWorktree exactly once, with the correct name
  • every run had exactly one preceding tool call (ToolSearch, to load the deferred EnterWorktree schema)
  • the call happened 29–39s after session start in every run (killed 29–33s, completed 30–39s — fully overlapping)
  • every run received the same success result: Created worktree at <repo>/.claude/worktrees/<name> on branch <branch>
  • every run then ran pwd, and all 13 returned the correct worktree path

Despite that, 9 of 13 sessions re-rooted and 4 did not.

How the difference is observable

The only signal I found is external to the session: Claude Code derives a session's transcript directory under ~/.claude/projects/ from the session root. Runs that genuinely re-rooted got a directory slugged from the worktree path; runs that did not kept writing under the original project slug, even though their file writes were landing in the worktree.

That directory appears 34–41s after launch, i.e. at the EnterWorktree call, so it reflects the call's outcome rather than anything later in the run.

Why it matters

The repository in question is a shared working tree used by concurrent sessions, so worktree isolation is a correctness property, not a convenience. Two consequences:

  1. A session can believe it is isolated, pass the obvious pwd check, and still be half-attached to the original root.
  2. In my runs the partial-application state correlated perfectly (4/4) with the launching process being stopped mid-run, orphaning the session. I want to be explicit that I have not established causation for that second point — the correlation is clean but the mechanism is unknown, and it may well be incidental.

What I'd suggest

Either make the re-rooting atomic (both move, or neither and the call reports failure), or expose the session's actual root so a caller can verify it. Today there is no in-session check that distinguishes the two outcomes — pwd succeeds in both.

Workaround, for anyone hitting the same thing

Stop relying on a running session relocating itself. Create the worktree with git worktree add beforehand and start the session with that directory as its cwd. The session is then correctly rooted from process start and nothing has to move. This removed the failure entirely for me.

🤖 Generated with Claude Code

View original on GitHub ↗