Summary
The trace-claude-code plugin registers its record-only telemetry hook (hooks/record_event.sh) on the WorktreeCreate and WorktreeRemove events:
"WorktreeCreate": [{ "hooks": [{ "type": "command",
"command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/record_event.sh WorktreeCreate", "async": false }] }],
"WorktreeRemove": [{ "hooks": [{ "type": "command",
"command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/record_event.sh WorktreeRemove", "async": false }] }]
But per the Claude Code worktrees doc, a configured WorktreeCreate hook "replaces the default git worktree logic entirely" (https://code.claude.com/docs/en/worktrees, "Non-git version control"). record_event.sh is explicitly record-only — it reads stdin, optionally records, and always exit 0 with no stdout. So once this plugin is enabled, the harness treats the telemetry hook as the authoritative worktree creator, it returns no path, and worktree creation fails with:
WorktreeCreate hook failed: hook succeeded but returned no worktree path
(command: echo the path to stdout; http/callback: return hookSpecificOutput.worktreePath)
This breaks all worktree isolation while the plugin is enabled: claude --worktree <name>, EnterWorktree, and Agent(isolation:"worktree") (subagent worktrees). It is not path-dependent (we initially misattributed it to a spaces-in-path repo; native git worktree add works fine from the CLI because the CLI bypasses the hook — the breakage is purely the hook shadowing native creation).
Repro
- Enable
trace-claude-code in any git repo.
- Run
claude --worktree test (or dispatch Agent(isolation:"worktree")).
- Observe the "returned no worktree path" error. Native
git worktree add from a shell still works.
Impact
Silent capability loss: worktrees work until the plugin is enabled, then break with a confusing error that points at "WorktreeCreate hook" with no configured hook visible in settings.json (it's the plugin's hooks/hooks.json). Cost real debugging time.
Suggested fix
A record-only/observability hook should not register on WorktreeCreate/WorktreeRemove, since the harness treats those as the authoritative creator/remover (they replace native git), not as passive lifecycle notifications. Options:
- Drop
WorktreeCreate/WorktreeRemove from record_event.sh's registration; or
- If telemetry on those events is desired, have the hook do the real
git worktree add/remove and echo the path (i.e. be a true creator), guarded so it only acts when no other creator is present — but the simplest correct fix is to not claim these events for a record-only hook.
Workaround (for others hitting this)
Add a project-level WorktreeCreate/WorktreeRemove override hook that does git worktree add/remove (paths quoted) and echoes the worktree path to stdout. Because multiple hooks run and the harness uses the one that returns a path, this restores worktree creation while keeping the plugin's tracing. (Editing the plugin's cached hooks.json also works but reverts on plugin update.)
— Reported from a Claude Code session debugging this in a real project.
Summary
The
trace-claude-codeplugin registers its record-only telemetry hook (hooks/record_event.sh) on theWorktreeCreateandWorktreeRemoveevents:But per the Claude Code worktrees doc, a configured
WorktreeCreatehook "replaces the defaultgit worktreelogic entirely" (https://code.claude.com/docs/en/worktrees, "Non-git version control").record_event.shis explicitly record-only — it reads stdin, optionally records, and alwaysexit 0with no stdout. So once this plugin is enabled, the harness treats the telemetry hook as the authoritative worktree creator, it returns no path, and worktree creation fails with:This breaks all worktree isolation while the plugin is enabled:
claude --worktree <name>,EnterWorktree, andAgent(isolation:"worktree")(subagent worktrees). It is not path-dependent (we initially misattributed it to a spaces-in-path repo; nativegit worktree addworks fine from the CLI because the CLI bypasses the hook — the breakage is purely the hook shadowing native creation).Repro
trace-claude-codein any git repo.claude --worktree test(or dispatchAgent(isolation:"worktree")).git worktree addfrom a shell still works.Impact
Silent capability loss: worktrees work until the plugin is enabled, then break with a confusing error that points at "WorktreeCreate hook" with no configured hook visible in
settings.json(it's the plugin'shooks/hooks.json). Cost real debugging time.Suggested fix
A record-only/observability hook should not register on
WorktreeCreate/WorktreeRemove, since the harness treats those as the authoritative creator/remover (they replace native git), not as passive lifecycle notifications. Options:WorktreeCreate/WorktreeRemovefromrecord_event.sh's registration; orgit worktree add/removeand echo the path (i.e. be a true creator), guarded so it only acts when no other creator is present — but the simplest correct fix is to not claim these events for a record-only hook.Workaround (for others hitting this)
Add a project-level
WorktreeCreate/WorktreeRemoveoverride hook that doesgit worktree add/remove(paths quoted) and echoes the worktree path to stdout. Because multiple hooks run and the harness uses the one that returns a path, this restores worktree creation while keeping the plugin's tracing. (Editing the plugin's cachedhooks.jsonalso works but reverts on plugin update.)— Reported from a Claude Code session debugging this in a real project.