Skip to content

Agent tool with isolation: "worktree" stacks worktrees inside existing worktree sandbox #485

@zackees

Description

@zackees

Symptom

The Claude Code Agent tool, when invoked with isolation: "worktree", creates the new git worktree relative to the calling agent's current working directory. When that calling agent is itself running inside a worktree the harness previously created (i.e. cwd is already .claude/worktrees/<parent>/), the new worktree lands at:

.claude/worktrees/<parent>/.claude/worktrees/<child>/

Each additional level of sub-agent compounds the nesting. git worktree list in this repo currently shows a 4-deep stack on disk:

.claude/worktrees/split-graph/.claude/worktrees/split-analyzer/.claude/worktrees/rebase-472/.claude/worktrees/fix-lpc-stubs

Total path length on that one is ~220 characters before any source file is appended.

Why it matters

On Windows, paths past MAX_PATH (260) cause cargo build scripts (notably cc-rs, when compiling bzip2-sys / libz-sys and similar) to fail with fatal error C1081: 'file name too long'. cc-rs then retries and re-emits the kilobyte-sized PATH env var on every retry per source file. That stderr stream was being piped back to Claude verbatim by the Stop hook, which overflowed the 1M context window — the user's session became unrecoverable mid-task (see #481).

#482 truncated the hook stderr (symptom). #483 added a PreToolUse guard hook on Agent that refuses isolation: "worktree" when cwd is already inside .claude/worktrees/... (local workaround). Neither addresses the root cause: the harness's Agent worktree placement.

Suggested fix (upstream)

The Claude Code Agent tool should anchor isolation: "worktree" paths at the repo root (git rev-parse --show-toplevel), not at the calling agent's cwd. New worktrees would then always land at <repo_root>/.claude/worktrees/<name>/ regardless of where the spawning agent is running.

Alternative: refuse to create a worktree if git rev-parse --show-toplevel differs from the cwd's repo top-level (i.e. cwd is itself a worktree, not the main checkout) and surface a clear error.

Workaround in this repo

The PreToolUse hook in #483 (ci/hooks/worktree_guard.py) detects the nested case and denies it before the harness creates the worktree. This is fbuild-local and should be retired once the harness behavior is fixed.

Links

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status
    Triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions