[BUG] WorktreeCreate hooks are unreachable in Cowork

Status Open
Maintainer reply None cached
Activity 0 comments · opened Aug 27, 2026

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 status clean)
  • git 2.34.1
  • ~/.claude/settings.json contains a valid hooks.WorktreeCreate entry

What Should Happen?

Expected

Either:

  • worktree isolation works, since the connected folder is a git repo; or
  • the configured WorktreeCreate hook 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

  1. mkdir -p ~/Claude/Sandbox && cd ~/Claude/Sandbox && git init -b main . && echo x > README.md && git add -A && git commit -m init
  2. Create a Cowork project bound to ~/Claude/Sandbox.
  3. Add to ~/.claude/settings.json:
   { "hooks": { "WorktreeCreate": [ { "type": "command",
     "command": "bash -c 'echo FIRED >> /tmp/wt-hook-fired.log; exit 1'" } ] } }
  1. In a new chat in that project, ask for a subagent spawned with isolation: "worktree".
  2. Observe the error above. Observe that /tmp/wt-hook-fired.log does 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:

  1. 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.

  1. A session was killed mid-commit, leaving index.lock and HEAD.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.

  1. A session's git add -A swept 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

  1. Consult WorktreeCreate hooks before the isGitRepo() guard, or at minimum when the guard

fails. This alone makes the workaround real and lets users build the missing support.

  1. Fix the error message to name only the condition actually evaluated.
  2. 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.

  1. 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.

View original on GitHub ↗