EnterWorktree / isolation: "worktree" creates nested worktrees when CWD drifts after context compaction

Resolved 💬 2 comments Opened Feb 23, 2026 by zepfu Closed Mar 23, 2026

Description

When an orchestrator agent dispatches subagents with isolation: "worktree", context compaction can leave the orchestrator's CWD pointing inside a previous worktree path. Subsequent worktree dispatches then nest inside the previous worktree instead of being created at the repository root. This can go 3+ levels deep and, critically, can cause agents to bypass worktree isolation entirely and commit directly to the main branch.

Reproduction Steps

Path A: Context compaction mid-session

  1. Start a session in a git repository (e.g., /home/user/projects/myrepo/)
  2. Dispatch a subagent with isolation: "worktree" — creates .claude/worktrees/agent-XXXXXXXX/ correctly
  3. Continue working until context compaction triggers (autocompact or manual)
  4. After compaction, the <env> block is reconstructed from current process state — CWD is now .claude/worktrees/agent-XXXXXXXX/
  5. Dispatch another subagent with isolation: "worktree" — new worktree is created at .claude/worktrees/agent-XXXXXXXX/.claude/worktrees/agent-YYYYYYYY/ (nested)
  6. Repeat — nesting goes deeper with each compaction cycle

Path B: Session continuation after context limit

  1. Start a session, dispatch subagents with isolation: "worktree"
  2. Session hits context limit and continues into a new conversation
  3. The continued session's <env> block shows the CWD as the worktree path from the previous session (e.g., Primary working directory: /home/user/projects/myrepo/.claude/worktrees/agent-XXXXXXXX)
  4. All subsequent worktree dispatches nest from that stale CWD
  5. Each retry or new dispatch nests deeper

Observed Behavior

git worktree list output from a real session:

/home/user/projects/myrepo                                                                                                     develop
/home/user/projects/myrepo/.claude/worktrees/agent-aba5b87b/.claude/worktrees/agent-a1684db4                                   (nested level 2)
/home/user/projects/myrepo/.claude/worktrees/agent-aba5b87b/.claude/worktrees/agent-a1684db4/.claude/worktrees/agent-a643979b  (nested level 3)
/home/user/projects/myrepo/.claude/worktrees/agent-aba5b87b/.claude/worktrees/agent-ae22c7e3                                   (nested level 2)
/home/user/projects/myrepo/.claude/worktrees/agent-ad348c0b                                                                    (correct level 1)

The nesting tree:

agent-aba5b87b/                          <- original worktree (cleaned up but dir remains)
  .claude/worktrees/
    agent-a1684db4/                      <- first retry (nested level 2)
      .claude/worktrees/
        agent-a643979b/                  <- second retry (nested level 3)
    agent-ae22c7e3/                      <- different agent, also nested

The session's <env> block at start showed Primary working directory: .../agent-aba5b87b, confirming the stale CWD was carried from a previous session continuation.

Safety Impact

This is not just a cosmetic issue. When nesting goes deep enough, worktree creation can fail silently, causing the agent to fall back to the current CWD — which may be checked out on develop or main.

Observed data loss scenario: A junior agent was dispatched with isolation: "worktree" from a double-nested CWD. The worktree creation failed silently. The agent fell back to the parent directory, which was checked out on develop, and committed directly to develop — bypassing the branch isolation and merge-review process entirely.

This defeats the entire purpose of worktree isolation — agents that should be on isolated branches end up with direct write access to protected branches. In a worst case, this could introduce broken code, conflicts, or security issues directly into a mainline branch with no review gate.

Root Cause

Two factors combine:

  1. CWD drifts into worktree paths and persists across compaction/continuation. Context compaction reconstructs the <env> block from current process state, and session continuation carries the CWD from the previous session. In both cases, if the CWD was inside a worktree, it stays there — the orchestrator has no mechanism to detect or correct this.
  1. EnterWorktree creates worktrees relative to CWD. It does not verify that CWD is the actual repository root. If CWD is already inside a worktree, the new worktree nests inside it.
  1. Silent fallback on failure. When deeply nested worktree creation fails (e.g., path too long, git limitations), the agent silently falls back to the current directory instead of erroring out. This means the isolation guarantee is silently dropped.

Expected Behavior

EnterWorktree should resolve to the git repository root (via git rev-parse --show-toplevel, following worktree .git files back to the main repo) before creating a new worktree. Worktrees should always be created at <repo-root>/.claude/worktrees/<name>, regardless of the current CWD.

Additionally, EnterWorktree should detect if it is being invoked from inside an existing worktree and either:

  • Automatically resolve to the main repository root, or
  • Refuse with a clear error message

Suggested Fix

Before git worktree add, resolve the true repository root:

# Follow .git file symlinks back to the main repo
REPO_ROOT=$(git -C "$(git rev-parse --git-common-dir)" rev-parse --show-toplevel 2>/dev/null || git rev-parse --show-toplevel)

Then create the worktree at $REPO_ROOT/.claude/worktrees/<name> instead of $(pwd)/.claude/worktrees/<name>.

Related Issues

  • #12748 — Feature request: add cwd parameter to Task tool (would allow explicit root specification)
  • #27343 — CLAUDE_PROJECT_DIR wrong in worktrees
  • #12885 — Working directory mismatch with worktrees
  • #10105 — Claude confuses git worktree directories with main repository
  • #9796 — Context compaction erases project-context instructions
  • #19471 — CLAUDE.md instructions ignored after compaction

Environment

  • Claude Code CLI
  • Linux (WSL2)
  • Git 2.43+
  • Orchestrator pattern: parent agent dispatching multiple subagents with isolation: "worktree" across a multi-hour session with multiple compaction cycles

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗