Skip to content

fix: Claude WorktreeCreate hook read wrong stdin fields, breaking worktree bootstrap#769

Merged
theoephraim merged 1 commit into
mainfrom
fix/claude-worktree-hook-payload
Jun 10, 2026
Merged

fix: Claude WorktreeCreate hook read wrong stdin fields, breaking worktree bootstrap#769
theoephraim merged 1 commit into
mainfrom
fix/claude-worktree-hook-payload

Conversation

@theoephraim

Copy link
Copy Markdown
Member

Problem

The WorktreeCreate hook (.claude/hooks/setup-worktree.sh) read worktree_path and base_commit from the hook's stdin payload — but Claude Code sends neither field. Both jq lookups returned the string "null", so git worktree add failed and worktree creation aborted entirely (WorktreeCreate has no fallback to the built-in git worktree add; any non-zero exit kills the operation).

Captured from a real invocation, the actual payload is:

{"session_id": "...", "transcript_path": "...", "cwd": "...", "hook_event_name": "WorktreeCreate", "name": "agent-..."}

Note the field is name — the Claude Code docs call it worktree_name, and the documented base_path field isn't sent either. There is no path or base-commit field at all: the hook is expected to choose both itself and print the chosen path to stdout.

Fix

  • Read the name via .name // .worktree_name (robust to either spelling, with a session-id-based fallback if both are missing)
  • Build the worktree path as <repo>/.claude/worktrees/<name> and base the worktree on the repo's current HEAD
  • Branch naming (claude/<name>), bun install + bun run build:libs, and stdout/stderr discipline unchanged

Verification

Triggered real worktree creations by spawning worktree-isolated subagents: the worktree was created at .claude/worktrees/agent-… on branch claude/agent-… with node_modules present and libs built before the agent started. Probe worktrees/branches were cleaned up afterwards.

The hook read worktree_path and base_commit from the hook input, but
Claude Code sends neither — the real payload only contains the worktree
name (as 'name', though docs call it 'worktree_name'). Both jq lookups
returned the string "null", so git worktree add failed and worktree
creation aborted entirely.

The hook now reads .name // .worktree_name (with a session-id fallback),
chooses the worktree path itself under .claude/worktrees/, and bases the
worktree on the repo's current HEAD. Verified end-to-end by spawning
worktree-isolated agents: deps installed and libs built before handoff.
@theoephraim theoephraim merged commit c11f7fb into main Jun 10, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant