[BUG] WorktreeCreate hook stdin payload doesn't match documentation — Workflow runtime sends 'name', docs say 'worktree_name' + 'base_path' + 'source_ref'

Resolved 💬 3 comments Opened Jun 5, 2026 by Aiadan Closed Jul 12, 2026

Environment

  • Claude Code: 2.1.165
  • Platform: Windows 11 Home (10.0.26200)
  • git: 2.45.1.windows.1
  • Hook: user-level WorktreeCreate command hook in ~/.claude/settings.json

Summary

The hooks documentation (code.claude.com/docs hooks reference, WorktreeCreate section) specifies this stdin payload, with the hook expected to construct the path from base_path + worktree_name and honor source_ref:

{
  "session_id": "...",
  "transcript_path": "...",
  "cwd": "...",
  "hook_event_name": "WorktreeCreate",
  "worktree_name": "feat-auth",
  "source_ref": "main",
  "base_path": "<project>/.worktrees"
}

What the Workflow runtime (agents spawned with opts.isolation: 'worktree' from a Workflow script) actually delivers on stdin in 2.1.165 is:

{ session_id, transcript_path, cwd, hook_event_name, name }

i.e. the worktree name arrives under name (not worktree_name), and base_path and source_ref are absent entirely. A hook written against the documented schema fails on every Workflow-isolated agent; the agent then dies pre-launch and the workflow's parallel() slot resolves to null.

(Older third-party hooks in the wild were written against an apparently earlier shape that included an explicit worktree_path — that field isn't sent anymore either, so there appear to be at least three payload generations across versions/entry-points.)

Reproduction

  1. Register a WorktreeCreate hook whose failure message echoes the keys it received:
// minimal repro hook
const fs = require('fs');
const data = JSON.parse(fs.readFileSync(0, 'utf8') || '{}');
if (!data.worktree_name || !data.base_path) {
  process.stderr.write('got keys: ' + Object.keys(data).join(', ') + '\n');
  process.exit(1);
}
  1. Run any Workflow script that spawns an agent with { isolation: 'worktree' }.

Expected

Payload matches the documented schema (worktree_name, base_path, source_ref), or the docs describe the per-entry-point payloads that are actually sent.

Actual

Workflow fails with (verbatim from the workflow failure log):

parallel[0] failed: WorktreeCreate hook failed: ... : got keys: session_id, transcript_path, cwd, hook_event_name, name

Impact

  • Any WorktreeCreate hook written from the documentation breaks Workflow worktree isolation completely (all isolated agents fail pre-launch).
  • Without base_path, the hook must hard-code knowledge that workflow worktrees live under <cwd>/.claude/worktrees/.
  • Without source_ref, the hook cannot honor the documented worktree.baseRef semantics ("fresh" vs "head") and has to guess; for agent isolation, HEAD is the only sensible default, but that's an inference, not a contract.

Suggested fix

Either send the documented fields (worktree_name, base_path, source_ref) from the Workflow runtime path, or update the docs to enumerate the real per-entry-point payloads. Given #36205/#39281/#29716/#57209 show Worktree hook dispatch differs per entry point, a single documented schema that all entry points actually conform to would resolve the whole family.

Related

  • #37611, #36205, #39281, #29716, #57209 — Worktree hook dispatch inconsistencies across entry points
  • Companion report: #65645 (Workflow-agent worktrees never cleaned up)

View original on GitHub ↗

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