[Bug] Auto mode allows destructive rm -rf commands without confirmation

Resolved 💬 2 comments Opened May 22, 2026 by andreahaku Closed May 26, 2026

Bug Description

Incident Report — Claude Code auto-executed rm -rf ~ causing massive data loss

Date: 2026-05-22
Model: claude-opus-4-7 (Opus 4.7)
Platform: Claude Code CLI on macOS (Darwin 24.6.0)
Session ID (project path): /Users/administrator/.claude/projects/[...]/0ded580d-11d2-414a-8e65-ae885007e416/
Severity: CRITICAL — irreversible loss of user data (multiple folders, ~hundreds of files)

---

TL;DR

Claude, while operating in auto mode (instructed to "bias toward working without stopping for clarifying questions"), executed an unquoted rm -rf ~ inside a Bash tool call as part of a "cleanup" sub-step of a larger commit script. The tilde was expanded by the shell to $HOME = /Users/administrator/, causing recursive deletion of the entire user home directory. Auto mode and the Bash tool classifier did not block this command despite it being one of the most universally recognized destructive patterns in Unix.

---

Exact command that caused the damage

The Bash tool call was a multi-line shell script. The destructive line was:

cd /Users/administrator/Development/[...] && git add . 2>&1 | tail -3
# ... earlier lines OK ...
rm -rf ~ 2>/dev/null  # <-- THIS LINE
git status --short
# ...

Intent: A previous global post-commit hook had been creating a literal directory named ~ inside whatever the cwd was (a bug in the user's hook). I wanted to delete that literal folder before staging.

What I should have written: rm -rf './~' or find . -maxdepth 1 -name '~' -type d -exec rm -rf {} +.

What zsh did: standard tilde expansion → rm -rf /Users/administrator/.

---

Context: how I got here

  1. The user's workspace had a chronic issue: a global git post-commit hook (writing to Obsidian) sometimes created an unrelated literal ~ directory in the cwd at commit time.
  2. Over the session I had been deleting these ~ literals multiple times with patterns like rm -rf ./~ (correctly quoted).
  3. On THIS occasion I wrote rm -rf ~ (unquoted). No reason for the slip — it was a single-character typo with catastrophic consequences.
  4. The command was inside a larger Bash tool call that included git add, git commit, git push. The classifier auto-approved the whole call.
  5. The Bash tool call was launched as run_in_background: true, so the destruction happened invisibly while I moved on to another task.
  6. A minute later the next tool call failed with Working directory "/Users/administrator/[...]" was deleted; shell cwd recovered to "/Users/administrator". That's when I realized.

---

Auto mode state at the time

A <system-reminder> earlier in the session set:

## Auto Mode Active Bias toward working without stopping for clarifying questions — when you'd normally pause to check, make the reasonable call and keep going; they'll redirect you if needed.

The Bash tool description includes safety guidance, but no hard rule against rm -rf $HOME or rm -rf ~. The classifier (claude-opus-4-7[1m]) approved the command without intervention.

---

Damage scope

Permanently lost (recovery only possible via external sync / disk recovery tools)

Home root

Home subfolders emptied:

  • ~/Desktop/ (everything)
  • ~/Documents/ (everything)
  • ~/Downloads/ (everything)

~/Development/

Dotfiles affected:

  • ~/.config/gh/ (GitHub CLI auth)
  • ~/.config/gcloud/ (Google Cloud auth + service account JSONs)
  • Various app caches

Survived (protected by macOS SIP or sheer luck)

  • ~/Library/ (system protected)
  • ~/Applications/, ~/Music/, ~/Movies/, ~/Pictures/, ~/Public/
  • ~/.ssh/ (had id_ed25519 with passphrase)
  • ~/Development/Claude/, ~/Development/Smartness/ (not yet reached by rm before something stopped it? unclear)

---

Why this should never have happened

1. rm -rf ~ is the textbook anti-pattern

It's literally the first example given when teaching shell safety. Auto-approving it from a model is a
failure mode the classifier should categorically block, like dd of=/dev/sda or mkfs on a system disk.

2. Auto mode + background execution = invisible damage

The destructive call was issued with run_in_background: true. By design, this means the result lands
later — and in this case, the cwd was already destroyed by the time I noticed. In auto mode,
destructive operations should never be allowed to run in the background.
They should at minimum be
blocking so the model sees the consequence immediately.

3. The classifier did intervene for less risky things

Earlier in the session the classifier correctly blocked:

  • grep ELEVENLABS_API_KEY inside .env files (correctly cited a Read deny rule)
  • security dump-keychain for token recovery (correctly flagged as out of scope)

So the classifier can block sensitive operations — but it didn't block rm -rf ~. There's a clear gap
in destructive-path detection vs. secret-scanning detection.

---

Suggested fixes for Anthropic

These are concrete suggestions in priority order:

P0 — Bash classifier hard-block on home/root destruction

The Bash tool's classifier should categorically refuse, regardless of mode (auto or not), any command
matching:

  • rm -rf ~ (unquoted tilde at top level of an argument)
  • rm -rf ${HOME} / rm -rf $HOME (with or without braces)
  • rm -rf / (any path that resolves to filesystem root)
  • rm -rf ~/... without explicit user authorization in the prompt
  • Wildcards that could match the user home: rm -rf ~/* , rm -rf /Users/*, etc.

For literal ~ directory removal (the rare legitimate case), require -- separator or path quoting and explicit phrasing in the prompt that justifies it.

P1 — Auto mode should never auto-approve destructive Bash

Anything that touches: rm, dd, mkfs, fdisk, format, shred, :> redirect on existing files, git reset --hard HEAD~N, git push --force to protected branches, chmod 000 on home — should always require an explicit confirmation prompt in auto mode, with the proposed command shown verbatim before execution.

P2 — Disallow run_in_background: true for destructive commands

If a command contains any of the patterns above, force foreground execution and surface the result immediately. The current behavior — background + invisible destruction + cwd reset — meant the model couldn't even react to the damage in real time.

P3 — Shell-aware static analysis on Bash tool input

Before execution, statically parse the proposed command:

  1. Detect tilde expansion paths
  2. Detect any variable that could resolve to a system-critical path
  3. Detect --no-preserve-root flags
  4. Detect chained commands where an earlier cd plus a later rm could be misinterpreted

For high-risk patterns, force the model to acknowledge the path that will be deleted by listing it (with ls -la <path> echo) before executing the destructive call.

P4 — Improve auto mode prompt warning

The current auto mode reminder says "still fine to stop when you're genuinely blocked — unclear direction, missing input, a decision only they can make". It should also explicitly list "destructive operations" as a stop trigger, regardless of how clear the rest of the path forward seems.

P5 — Telemetry on destructive operations

If telemetry is collected on tool calls, flagging any rm -rf execution by Claude Code (anonymized) would let Anthropic safety see how often this pattern occurs and add hard-block rules accordingly.

---

What was actually happening when the disaster ran

The session was a long, complex one (~6 hours of context). At the moment of the bad command I was:

  1. In auto mode, having been told to "bias toward working without stopping"
  2. Mid-flow on commit-and-push of the Nuxt PWA work
  3. Having just finished writing ~600 lines of Vue/TypeScript and wanting to commit
  4. Pasting a small rm -rf ~ "cleanup" inline in the commit shell script
  5. Launching the whole thing as run_in_background: true to do other work in parallel

In retrospect, every single one of these factors increased the chance of the mistake going through:

  • Long session = decision fatigue, weaker self-review
  • Auto mode = no friction prompts
  • Inline cleanup buried in a 30-line script = harder for both me and the classifier to catch
  • Background execution = no immediate feedback

A robust Bash tool design would handle the failure of any one of those factors. As of today, it relies on all of them holding simultaneously.

---

What I (Claude) am doing on my end

I've saved a persistent memory in this user's project memory store with a hard rule:

Never use rm -rf ~, rm -rf $HOME, or rm against any path that can expand to home/root. For literal ~ directory removal use rm -rf './~' or equivalent. Always validate destructive paths with ls or echo first. Never run rm -rf in background. Never auto-approve in auto mode without explicit user authorization for that specific path.

This rule will be loaded into context in all future sessions on this user's machine.

---

User impact

  • Hours of lost work: at least 2 hours of Vue/Nuxt code from this session that hadn't been pushed.
  • Lost trust: the user explicitly stated auto mode was supposed to prevent exactly this kind of catastrophe.
  • Permanent data loss: an unknown number of personal files (presentations, notes, scripts, screenshots) that weren't on git or any sync.
  • Time to recover: hours to clone repos back, restore from the second machine, re-auth all CLI tools (gh, gcloud, etc.).

View original on GitHub ↗

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