[BUG] WorktreeCreate hook exits status 1 (post-checkout failure) causes silent indefinite hang

Resolved 💬 3 comments Opened Feb 23, 2026 by assafeisr Closed Mar 23, 2026

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

  1. Have a repo with a post-checkout git hook that either fails or takes >60 s.
  2. Configure a WorktreeCreate hook in ~/.claude/settings.json with "timeout": 60.
  3. Run claude --worktree my-new-branch.
  4. The WorktreeCreate hook script calls git worktree add, which triggers post-checkout, which fails/times out.
  5. The hook script exits with status 1 (no output on stdout).
  6. 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:

  1. Print a clear error message (e.g. "WorktreeCreate hook failed with exit code 1")
  2. Exit cleanly rather than hanging

Related: #27467 (status 0 with unexpected stdout produces the same silent hang)

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗