Agent tool `isolation: "worktree"` cannot target an existing worktree; every isolated dispatch mints a fresh one

Status Open
Reported on v2.1.282
Maintainer reply None cached
Activity 0 comments · opened Sep 25, 2026

Environment

  • Claude Code 2.1.282, headless (claude -p), --permission-mode bypassPermissions
  • macOS 26.6.2, arm64
  • Reproduced with hooks, plugins and MCP servers disabled.
  • Flags: --safe-mode --setting-sources "" --settings '{"disableAllHooks":true}' --strict-mcp-config --mcp-config '{"mcpServers":{}}'. The debug log reports "Registered 0 hooks from 2 plugins" (the built-in agents-md and telemetry) and "Found 0 total hooks in registry".

Summary

A subagent dispatched with isolation: "worktree" always gets a new worktree under .claude/worktrees/agent-<id>. The Agent tool takes description, isolation, model, prompt, run_in_background and subagent_type. The isolation description reads:

Isolation mode. "worktree" creates a temporary git worktree so the agent works on an isolated copy of the repo. "remote" launches the agent in a remote cloud environment (always runs in background; availability is gated).

No parameter names an existing worktree or branch. An isolated agent that must continue work parked in another worktree is refused when it reaches that tree. That refusal protects isolation. The gap is that no isolation request can make the parked tree the agent's own.

Minimal reproduction

In a throwaway repo with one commit:

  1. Dispatch subagent A with isolation: "worktree". It runs git checkout -b parked-work, appends a line to README.md, and commits (711b3b5 parked change). The result reports worktreePath: <repo>/.claude/worktrees/agent-a342... and worktreeBranch: worktree-agent-a342.... The tree stays on disk on parked-work.
  2. Dispatch subagent B with isolation: "worktree". It gets a new tree, agent-a8e5....
  3. B runs git branch --list parked-work. Accepted: + parked-work (checked out in another worktree).
  4. B runs git -C <A's tree> log --oneline -1. Refused (paths shortened):
This agent is isolated in the worktree <B's tree>, but this command redirects git to the shared checkout via -C. Refusing to run it — a worktree-isolated agent's git operations must target its own worktree. Run the equivalent from <B's tree> without the redirect.
  1. B runs cd <A's tree> && git log --oneline -1. Refused:
This agent is isolated in the worktree <B's tree>, but this command changes directory to the shared checkout (<A's tree>) before running git. Refusing to run it — a worktree-isolated agent's git operations must target its own worktree. Run the equivalent from <B's tree> without the redirect.

git -C <A's tree> status --short is refused with the same text as step 4. The refusal also calls A's worktree "the shared checkout", which it is not.

Observed vs expected

Observed: B can continue parked-work only by copying the branch into its own tree, for example git checkout -b parked-work-r2 711b3b5. A caller outside isolation must later move the commits back. Uncommitted state in A's tree is unreachable, and each resume leaves another worktree on disk.

Expected: an option on the isolation request, such as a worktree path or branch name, that places the agent in an existing worktree of the same repository when no other agent holds it. The existing refusal would then protect the tree the agent was given.

Evidence (public issues, for reference only)

  • bobmatnyc/trusty-tools#8161: resuming a parked worktree needs the branch-copy workaround
  • bobmatnyc/trusty-tools#8494: a PR branch held by a parked worktree cannot be checked out from a new isolated dispatch

View original on GitHub ↗