fix: Claude WorktreeCreate hook read wrong stdin fields, breaking worktree bootstrap#769
Merged
Merged
Conversation
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The
WorktreeCreatehook (.claude/hooks/setup-worktree.sh) readworktree_pathandbase_commitfrom the hook's stdin payload — but Claude Code sends neither field. Bothjqlookups returned the string"null", sogit worktree addfailed and worktree creation aborted entirely (WorktreeCreate has no fallback to the built-ingit 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 itworktree_name, and the documentedbase_pathfield 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
.name // .worktree_name(robust to either spelling, with a session-id-based fallback if both are missing)<repo>/.claude/worktrees/<name>and base the worktree on the repo's currentHEADclaude/<name>),bun install+bun run build:libs, and stdout/stderr discipline unchangedVerification
Triggered real worktree creations by spawning worktree-isolated subagents: the worktree was created at
.claude/worktrees/agent-…on branchclaude/agent-…withnode_modulespresent and libs built before the agent started. Probe worktrees/branches were cleaned up afterwards.