Dispatched agents with isolation="worktree" cannot Edit/Write files in their own worktree (.claude/worktrees denied by policy)
Summary
When an agent is spawned via the Agent tool with isolation: "worktree", the harness creates a git worktree at <repo>/.claude/worktrees/agent-<id>/ and checks out a branch there. The agent can Read and run Bash commands in that worktree, but every Edit, Write, and sed -i attempt on source files inside the worktree is silently denied — no permission prompt, no explanation. The agent is effectively dead on arrival for any implementation task.
Repro
- On macOS (Darwin 24.6.0), Claude Code (Opus 4.6, default permission mode).
- Dispatch a general-purpose agent to any repo with
isolation: "worktree"and a trivially simple task like "delete one unused import on line N". - Agent will:
- create the branch successfully
Readthe file successfully- attempt
Edit→ denied (no error message beyond "permission denied") - retry with
Write→ denied - retry with
Bashsed -i→ denied - eventually give up and report the problem back
Happens 100% reproducibly. Confirmed across 3 parallel agents today.
Root cause (best guess)
The harness appears to have a broad deny write policy on the .claude/** path prefix — presumably to protect session state files like settings.local.json. That policy is over-reaching into the agent's own worktree, which happens to live at .claude/worktrees/agent-<id>/....
Evidence it's a harness policy, not the filesystem:
- Files are physically writable:
-rw-r--r--, correct owner. - The parent session (running outside the worktree) can write into those same worktree paths without issue. Only dispatched agents are blocked.
- All writes fail, not just writes to session-state files.
Proposed fix
Move worktrees out of .claude/ entirely. Put them in a sibling directory to the repo rather than inside it:
/Users/<user>/dev/<project>/ # main repo
/Users/<user>/dev/<project>-worktrees/ # managed by harness
├── agent-a53a5798/ # worktree for spawned agent
├── agent-aaf861c0/
└── ...
Or a centralised location like ~/.claude/worktrees/<project>/agent-<id>/.
Reasons not to use /tmp/:
- tmpfiles / cron can clean it up mid-task
- loses state on reboot
- macOS
/tmpreaps aggressively
Keeping the worktrees outside .claude/ removes them from the deny policy's path. It also makes the worktrees visible to the user outside the session (useful for debugging, cleaning up abandoned branches, etc.).
Interim request
At minimum, return a clear error message when a write is denied by the sandbox policy. Today the agent just gets "denied" and has to guess at the cause. A message like:
Edit denied: writes to .claude/** are blocked by harness policy. This path
is protected session state; move the file or ask your parent session.
…would let agents recover faster or at least report a meaningful reason to the user.
Workaround
For now: don't use isolation: "worktree" for implementation work. Either:
- Do the work inline in the main repo
- Spawn agents without worktree isolation and manually juggle branches
- Have the dispatched agent emit a patch and apply it from the parent session (the parent can write into the worktree; only dispatched agents can't)
Env
- macOS Darwin 24.6.0
- Claude Code — Opus 4.6 (1M context)
- Fish shell
- Permission mode: default
- Observed in repo: Rust workspace (ctux)
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗