[BUG] WorktreeCreate hook returning a path outside the repository is always refused: "git could not be run to resolve it"
What's Wrong?
A WorktreeCreate hook that creates a valid git worktree outside the repository and prints its path is always refused by Claude Code's git-identity verification:
Refusing to use /Users/me/workspace/worktrees/my-repo/<name> as an isolation worktree: git could not be run to resolve it, so its git identity could not be verified. Isolation is refused rather than assumed — recreate the worktree (or remove the corrupt .git entry) and retry.
The worktree itself is healthy: it is registered in git worktree list, git -C <path> status works, the path contains no symlinks and no ./.. segments. The hook's stdout is clean (only the path on the last line; git output redirected to stderr).
Control test: the identical hook returning a path inside the repository ($repo_root/.claude/worktrees/$name) is accepted, and the session runs in it. So the hook mechanics and output parsing are fine — the external location is the trigger.
The refusal reproduces identically for all three creation paths: claude --worktree, the EnterWorktree tool, and Agent(isolation: "worktree") subagents, and in completely fresh sessions.
What Should Happen?
Per https://code.claude.com/docs/en/worktrees.md and hooks.md, a WorktreeCreate hook "replaces default git behavior" and may return any directory; paths outside .claude/worktrees/ are documented as accepted with a one-time approval when entered. Instead, verification hard-fails before any approval prompt, and the failure message ("git could not be run to resolve it") is wrong — git runs fine against the directory.
Steps to Reproduce
~/.claude/settings.json:
{
"hooks": {
"WorktreeCreate": [
{ "hooks": [ { "type": "command", "command": "~/.claude/hooks/worktree-create.sh" } ] }
]
}
}
~/.claude/hooks/worktree-create.sh(chmod +x):
#!/bin/bash
set -euo pipefail
input=$(cat)
name=$(jq -r '.name' <<<"$input")
cwd=$(jq -r '.cwd' <<<"$input")
repo_root=$(git -C "$cwd" rev-parse --show-toplevel)
repo=$(basename "$repo_root")
dir="$HOME/workspace/worktrees/$repo/$name"
mkdir -p "$(dirname "$dir")"
git -C "$repo_root" worktree add -b "$name" "$dir" >&2
echo "$dir"
- From any git repo:
claude --worktree mytest -p "pwd" - Observe the refusal. Then
git worktree listshows the worktree was created and is valid. - Change the script's
dir=to"$repo_root/.claude/worktrees/$name"and repeat — it works.
Ruled out (each re-tested in a fresh headless session)
permissions.additionalDirectories: ["~/workspace/worktrees"]in user settings — same refusal--add-dir ~/workspace/worktrees— same refusal--settings '{"sandbox":{"enabled":false}}'— same refusal- symlinks in the path — none (
realpathidentical); no./..segments --debuglogs contain nothing beyond the refusal message; the underlying git spawn error is not logged
Error Messages/Logs
Error creating worktree: Refusing to use /Users/me/workspace/worktrees/my-repo/mytest as an isolation worktree: git could not be run to resolve it, so its git identity could not be verified. Isolation is refused rather than assumed — recreate the worktree (or remove the corrupt .git entry) and retry.
Claude Code Version
2.1.241
Platform
Anthropic API / macOS (Darwin 25.5.0), git 2.53.0 (homebrew), shell zsh
Is this a regression?
Unknown — first attempt at an external-path WorktreeCreate hook on this machine.