Background/agent isolation: "worktree" creates worktrees without firing the WorktreeCreate hook

Resolved 💬 3 comments Opened May 19, 2026 by KingMob Closed Jun 18, 2026

Summary

Worktrees created by the harness's background/agent worktree isolation (isolation: "worktree" on the Agent tool, FleetView-spawned background tasks) are created via a direct git worktree add into .claude/worktrees/<slug> and do not fire the WorktreeCreate hook event. This makes the path uninterceptable, breaking jj (Jujutsu) repos where a WorktreeCreate hook is the documented mechanism for converting worktrees into jj workspaces.

This is the same class of defect as #36205 (the EnterWorktree tool not firing WorktreeCreate), but for the background-isolation creation path rather than the in-session tool.

Environment

  • Claude Code: 2.1.144
  • OS: macOS 26.4.1 (build 25E253)
  • VCS: Jujutsu (jj) colocated repo with a git backend

The three worktree-creation paths

There are three ways a worktree gets created, and only two are interceptable:

| Path | Fires WorktreeCreate? | Interceptable? |
|---|---|---|
| Terminal claude --worktree | ✅ Yes | ✅ via WorktreeCreate hook |
| EnterWorktree tool (Desktop / mid-session) | ❌ No (#36205) | ⚠️ only via a PreToolUse:EnterWorktree workaround |
| Background / agent isolation: "worktree" | ❌ No | ❌ No event at all |

The first two have workarounds. The third does not: there is no tool call to match with PreToolUse (creation happens during session bootstrap, before the agent runs), and WorktreeCreate is never emitted.

Steps to reproduce

  1. In a jj (or any non-git-native) repo, configure a WorktreeCreate hook that converts the new worktree appropriately (e.g. jj workspace add).
  2. Spawn a background agent / task with isolation: "worktree" (or trigger a FleetView background task that uses worktree isolation).
  3. Inspect the resulting session's working directory.

Expected behavior

Background-isolation worktree creation fires the WorktreeCreate hook (same payload contract as the terminal --worktree path: name, cwd, and honoring the hook's stdout path contract), so existing tooling can convert/relocate the worktree.

Actual behavior

A plain git worktree add is performed into .claude/worktrees/<slug> with branch claude/<slug>. No hook fires. In a jj repo this yields a git-only worktree where jj commands silently resolve against the main repo's working copy (jj root points outside the worktree) — a data-loss footgun for commits.

Observed: six such .claude/worktrees/<slug> worktrees (branches claude/<slug>), none converted, despite a working WorktreeCreate hook that correctly handles the terminal --worktree path.

Impact

  • jj / non-git-native repos cannot reliably use background-agent worktree isolation; VCS operations in the worktree target the wrong working copy.
  • The WorktreeCreate hook is documented as the worktree-lifecycle interception point, but the most common automated path (background agents) bypasses it, making the hook contract effectively unreliable.

Suggested fix

Emit WorktreeCreate for all worktree-creation paths, including background/agent isolation: "worktree", with the same payload and stdout-path contract as the terminal --worktree path. Honoring the hook's returned path would additionally let the relocated/converted worktree be used as the session cwd, mirroring the --worktree behavior. Fixing this would also subsume the EnterWorktree workaround needed for #36205.

Related

  • #36205 — EnterWorktree tool does not fire WorktreeCreate (sibling defect, in-session tool path)

View original on GitHub ↗

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