claude-code - 💡(How to fix) Fix [BUG] Worktree exit prompt bypasses PreToolUse hooks — no project-level opt-out, causes data loss [1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#56349Fetched 2026-05-06 06:30:31
View on GitHub
Comments
1
Participants
2
Timeline
6
Reactions
0
Author
Timeline (top)
labeled ×5commented ×1

Error Message

Error Messages/Logs

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

Root Cause

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.

Fix Action

Fix / Workaround

Fragile workaround we discovered

Code Example

{
  "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
        }]
      }
    ]
  }
}

---

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

 1. Keep worktree
  2. Remove worktree

---

{
  "worktreeCleanup": "never"
}

---

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

---

{
  "matcher": "WorktreeCreate",
  "hooks": [{ "type": "command", "command": "true", "timeout": 5 }]
}
RAW_BUFFERClick to expand / collapse

Preflight Checklist

  • I have searched existing issues and this hasn't been reported yet
  • This is a single bug report (please file separate reports for different bugs)
  • 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.

  2. 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.

extent analysis

TL;DR

The issue can be mitigated by adding a no-op WorktreeCreate hook to skip the exit cleanup prompt, although a more robust solution involves implementing a project-level setting to disable worktree cleanup.

Guidance

  • Add a no-op WorktreeCreate hook to the .claude/settings.json file to potentially bypass the exit cleanup prompt.
  • Review the provided PreToolUse hooks configuration to ensure it is correctly blocking EnterWorktree and ExitWorktree actions.
  • Consider reaching out to the Claude Code developers to request a project-level setting to disable worktree cleanup, as proposed in the issue.
  • Be cautious of potential updates breaking the no-op WorktreeCreate hook workaround, as it is an undocumented side effect.

Example

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

Notes

The provided workaround using a no-op WorktreeCreate hook may not be a reliable long-term solution, as it relies on an undocumented side effect. A more robust solution would involve implementing a project-level setting to disable worktree cleanup.

Recommendation

Apply the workaround by adding a no-op WorktreeCreate hook, while also requesting a project-level setting to disable worktree cleanup from the Claude Code developers, as this would provide a more reliable and sustainable solution.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING