[BUG] Worktree exit prompt bypasses PreToolUse hooks — no project-level opt-out, causes data loss

Resolved 💬 3 comments Opened May 5, 2026 by anodynos Closed May 9, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

Claude Code's "Exiting worktree session" prompt bypasses PreToolUse hooks and offers to permanently delete worktrees, with no project-level setting to disable it. This has caused data loss.

I run a worktree-first workflow — 100% of development happens in git worktrees (7+ active at any time), main stays clean, and only a dedicated review+conclude pipeline manages worktree lifecycle.

The defense I built (worked for months)

Back in March 2026, I implemented PreToolUse hooks that block both EnterWorktree and ExitWorktree with exit 2:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "EnterWorktree",
        "hooks": [{
          "type": "command",
          "command": "echo 'BLOCKED: Use git worktree add directly, not EnterWorktree.' >&2 && exit 2",
          "timeout": 5
        }]
      },
      {
        "matcher": "ExitWorktree",
        "hooks": [{
          "type": "command",
          "command": "echo 'BLOCKED: Worktrees are only removed by /conclude.' >&2 && exit 2",
          "timeout": 5
        }]
      }
    ]
  }
}

This worked perfectly for months. Agents used git worktree add directly, never triggered the exit prompt, and our pipeline controlled worktree lifecycle end-to-end.

Then a CC update broke it

Around early May 2026, the interactive "Exiting worktree session" prompt appeared despite our hooks:

Exiting worktree session
You have 7 uncommitted files. These will be lost if you remove the worktree.

❯ 1. Keep worktree
  2. Remove worktree

Our hooks didn't fire because this prompt is not a tool call — it's built-in CLI chrome that bypasses the hook system entirely. Despite having defensive hooks in place for months, I was suddenly face-to-face with a prompt offering to destroy my work — and I lost work as a result.

This means hooks are not a reliable safety mechanism — if CC can bypass them via built-in UI flows, users cannot trust hooks as guardrails. I built exactly the defense the hooks system is designed for. It worked. Then a CC update introduced a parallel code path that silently bypasses it.

This is a widespread problem

At least 4 open issues document worktree-related data loss:

  • #46444 — 300+ files, 160+ hours permanently deleted by auto-cleanup
  • #48927 — Parallel subagent cleanup destroyed .git/ directory entirely
  • #38287 — Committed-but-unpushed work silently deleted (labeled data-loss, has repro)
  • #40850 — Model decided a worktree was "stale" and rm -rf'd it while another session used it

Additional related: #27753, #37611, #41089, #31969, #45737, #26725, #48405, #43730, #29436

What Should Happen?

  1. The exit prompt should respect PreToolUse hooks on ExitWorktree. If a project has blocked ExitWorktree via hooks, the built-in exit prompt should not appear. Hooks being bypassable by built-in UI flows undermines the entire hook system's reliability.
  1. A project-level setting should exist to disable worktree cleanup:
{
  "worktreeCleanup": "never"
}

Where:

  • "never" — no exit prompt, no auto-cleanup, no subagent sweep. The project manages worktree lifecycle.
  • "keep" — show the prompt but default to "Keep worktree" and never auto-delete without the prompt.
  • "prompt" (current default) — current behavior.

This should be settable in .claude/settings.json (project-level) so all sessions in the project inherit it.

  1. "Remove worktree" should not be one arrow-key away from "Keep worktree." A destructive action that permanently deletes branches and commits should require typing a confirmation phrase, not a single keypress. Double Ctrl+C should never trigger removal.

Error Messages/Logs

Exiting worktree session
You have 7 uncommitted files. These will be lost if you remove the worktree.

❯ 1. Keep worktree    Stays at /mnt/projects/AgenZen/.claude/worktrees/feat-AZ-556-leveled-context
  2. Remove worktree  All changes and commits will be lost.

Enter to confirm · Esc to cancel

No error — this is the prompt itself. The bug is that it appears at all when ExitWorktree is blocked by hooks.

Steps to Reproduce

  1. Create a project with a .claude/settings.json containing PreToolUse hooks that block EnterWorktree and ExitWorktree with exit 2 (see config in "What's Wrong?" above)
  2. Create a git worktree manually: git worktree add .claude/worktrees/test-branch -b test-branch
  3. Start a Claude Code session inside the worktree directory: cd .claude/worktrees/test-branch && claude
  4. Make some changes (edit a file, leave it uncommitted)
  5. Exit the session (Ctrl+C or /exit)
  6. Observe: The "Exiting worktree session — Keep/Remove worktree" prompt appears despite ExitWorktree being blocked by hooks
  7. Expected: No prompt should appear because ExitWorktree is blocked

Claude Model

Opus

Is this a regression?

Yes, this worked in a previous version

Last Working Version

Worked correctly from March 2026 through late April 2026 (exact version unknown — hooks successfully prevented the prompt for ~2 months). Broke around CC 2.1.120+.

Claude Code Version

2.1.126 (Claude Code)

Platform

Anthropic API

Operating System

Ubuntu/Debian Linux

Terminal/Shell

WSL (Windows Subsystem for Linux)

Additional Information

Fragile workaround we discovered

Via #37611, we found that adding a no-op WorktreeCreate hook causes the exit cleanup prompt to be skipped — but this is an undocumented side effect, not a feature:

{
  "matcher": "WorktreeCreate",
  "hooks": [{ "type": "command", "command": "true", "timeout": 5 }]
}

Combined with our EnterWorktree/ExitWorktree blocks, this may cover the prompt path — but it's fragile, could break in any update (just like our previous defense did), and doesn't protect against the subagent cleanup sweep.

We shouldn't need to reverse-engineer undocumented side effects to prevent a development tool from deleting our work.

Broader impact

This isn't just about our workflow. The fundamental issue is:

  • Hooks are supposed to be safety guardrails — but built-in UI flows bypass them
  • "Remove worktree" is a destructive, irreversible action — it deletes branches, commits, and all uncommitted work
  • Projects with long-lived worktrees have no opt-out — CC assumes all worktrees are ephemeral and disposable
  • 4+ open data-loss issues with no official response — users are losing days and weeks of work

A development tool should never permanently destroy work without explicit, informed, hard-to-accidentally-trigger consent. Please give us a setting to opt out.

View original on GitHub ↗

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