[BUG] WorktreeCreate hook exits status 1 (post-checkout failure) causes silent indefinite hang
Summary
When a WorktreeCreate hook exits with status 1, Claude Code hangs indefinitely instead of showing an error. This is distinct from #27467 (which covers status 0 with unexpected stdout). Both failure modes result in a silent hang, but the triggers and debug signatures are different.
Environment
- Claude Code v2.1.50
- macOS 15.3 (Darwin 25.3.0, arm64)
Root Cause
git worktree add fires the repo's post-checkout git hook when creating a new branch. If that hook fails (or takes longer than the 60 s WorktreeCreate timeout), git worktree add exits non-zero, the hook script exits with status 1, and Claude Code hangs.
In repos where post-checkout syncs all language dependencies (Python/Node/Go packages), this easily exceeds the timeout on a cold cache.
Steps to Reproduce
- Have a repo with a
post-checkoutgit hook that either fails or takes >60 s. - Configure a
WorktreeCreatehook in~/.claude/settings.jsonwith"timeout": 60. - Run
claude --worktree my-new-branch. - The
WorktreeCreatehook script callsgit worktree add, which triggerspost-checkout, which fails/times out. - The hook script exits with status 1 (no output on stdout).
- Claude Code hangs indefinitely — no error, no prompt, requires Ctrl-C.
Debug Log Evidence
When the hook exits status 1, the debug log shows Claude Code is _not_ stuck in a local loop — it opens TCP connections to api.anthropic.com and idles there indefinitely:
2026-02-23T18:34:18.286Z [DEBUG] WorktreeCreate [...worktree-create.sh] completed with status 1
2026-02-23T18:34:18.286Z [DEBUG] Hook output does not start with {, treating as plain text
After those two lines the log has no further entries, but lsof shows 2 ESTABLISHED TCP connections to api.anthropic.com:443 with no bytes buffered:
claude 48406 ESTABLISHED tcp ... 17.253.144.10:https
claude 48406 ESTABLISHED tcp ... 17.253.144.10:https
The process stays alive at ~0% CPU waiting indefinitely.
Contrast with Status 0 Hang (#27467)
| | #27467 (status 0, bad stdout) | This issue (status 1) |
|---|---|---|
| Hook exit code | 0 | 1 |
| Debug log | "Created hook-based worktree at: HEAD is now at ..." | "completed with status 1" |
| TCP connections | Not confirmed | 2 ESTABLISHED to api.anthropic.com |
| Recovery | Ctrl-C | Ctrl-C |
Workaround
Skip git hooks inside the WorktreeCreate script to prevent post-checkout from running during worktree creation:
# Use -c core.hooksPath=/dev/null so post-checkout doesn't run
git -C "$repo_root" -c core.hooksPath=/dev/null worktree add -b "$name" "$worktree_path" "$base_ref" >&2
This makes first-time worktree creation reliably complete in ~2 s regardless of what post-checkout does. Also add an idempotency check for re-runs when the worktree already exists:
worktree_path="$repo_root/.claude/worktrees/$name"
if git -C "$repo_root" worktree list --porcelain 2>/dev/null | grep -qF "worktree $worktree_path"; then
echo "$worktree_path"
exit 0
fi
Expected Behavior
When a WorktreeCreate hook exits non-zero, Claude Code should:
- Print a clear error message (e.g. "WorktreeCreate hook failed with exit code 1")
- Exit cleanly rather than hanging
Related: #27467 (status 0 with unexpected stdout produces the same silent hang)
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗