[BUG] WorktreeCreate hooks are unreachable in Cowork
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
In Claude Cowork, isolation: "worktree" on a subagent always fails, and the WorktreeCreate hook
the error message recommends as the workaround is never invoked. The isGitRepo() check runs
before hooks are consulted, and a Cowork session's working directory is never a git repository — so
the documented escape hatch is unreachable in the only configuration Cowork ever runs in.
Environment
- Claude Cowork, desktop app, macOS
- Connected folder is a git repository (
git init -b main, ≥1 commit,git statusclean) - git 2.34.1
~/.claude/settings.jsoncontains a validhooks.WorktreeCreateentry
What Should Happen?
Expected
Either:
- worktree isolation works, since the connected folder is a git repo; or
- the configured
WorktreeCreatehook is invoked, as the error message explicitly instructs.
Actual
Cannot create agent worktree: not in a git repository and no WorktreeCreate hooks are configured.
Configure WorktreeCreate/WorktreeRemove hooks in settings.json to use worktree isolation with
other VCS systems.
The hook is never executed. The error appears identically whether or not a hook is configured.
Error Messages/Logs
Steps to Reproduce
Reproduction
mkdir -p ~/Claude/Sandbox && cd ~/Claude/Sandbox && git init -b main . && echo x > README.md && git add -A && git commit -m init- Create a Cowork project bound to
~/Claude/Sandbox. - Add to
~/.claude/settings.json:
{ "hooks": { "WorktreeCreate": [ { "type": "command",
"command": "bash -c 'echo FIRED >> /tmp/wt-hook-fired.log; exit 1'" } ] } }
- In a new chat in that project, ask for a subagent spawned with
isolation: "worktree". - Observe the error above. Observe that
/tmp/wt-hook-fired.logdoes not exist.
Claude Model
None
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
Claude 1.37937.3 (28dcf5) 2026-08-26T19:52:45.000Z
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Other
Additional Information
What was ruled out
The negative result was not accepted at face value. Two rounds, and these confounds were eliminated:
| Hypothesis | How it was excluded |
|---|---|
| Hook not registered | Installer backed up, merged, and re-validated ~/.claude/settings.json; JSON confirmed valid and containing WorktreeCreate |
| Settings not reloaded | Each run used a brand-new chat; settings load at session start |
| Hook script path wrong | The registered command logged a marker before invoking the script. Marker never appeared either |
| Connected folder isn't really a repo | git status in it returns On branch main / nothing to commit, working tree clean |
| Hook ran but logged somewhere invisible | Probe v2 wrote to Mac paths, $HOME, /tmp, and every /sessions/*/mnt/*/ connected-folder mount — a sandbox-side write to a mount is visible on the Mac. Nothing appeared in any of them |
| One-off | Reproduced across two separate runs and two probe versions |
Impact
Cowork sessions cannot isolate concurrent work. Two Cowork projects bound to the same folder — a
documented and reasonable setup, since a project scoped to a subfolder can't reach shared reference
material — share one working tree. Observed consequences in three days of production use:
- An agent read another agent's in-flight artifact as settled fact and escalated a correct,
engineering-confirmed customer commitment as a customer-facing risk needing retraction. Two further
errors were then inherited from that write-up before it was caught.
- A session was killed mid-commit, leaving
index.lockandHEAD.lock; the next session was
blocked, did its work anyway, left it staged, and exited. Three hours of finished analysis sat
invisible until another session found it.
- A session's
git add -Aswept seven files belonging to a concurrently running session into an
unrelated commit, destroying their provenance.
Manual per-project worktrees mitigate (1) but introduce a new failure: a linked worktree's .git is a
pointer file into the main repo, so a session that loses write access there cannot commit at all.
That happened the day after adoption — a scheduled daily task ran degraded and could not save its own
output.
Suggested fixes, in order of value
- Consult
WorktreeCreatehooks before theisGitRepo()guard, or at minimum when the guard
fails. This alone makes the workaround real and lets users build the missing support.
- Fix the error message to name only the condition actually evaluated.
- Resolve the repository from the connected folder, not the session cwd. The session cwd is an
internal outputs directory and is never a repo, so the check as written can never pass in Cowork.
- Per-session worktrees as a per-folder opt-in — "isolate sessions in this folder": create on
session start, auto-merge and remove on clean exit, prompt only on conflict, subagents inherit.
This is the feature that would close both cross-project and same-project collisions, and agent
isolation, with one mechanism.
Sensible that this isn't the default — branches and merge conflicts are the wrong thing to hand
Cowork's primary audience. An opt-in for users whose connected folder is already a git repo seems
like the right shape.