Claude Code's Double Safety Failure: 717 GB and Broken Guards
One backslash. Four shell parsers. 717 gigabytes gone in under two minutes. That’s the post-mortem that’s been circulating in Claude Code communities — the story of an AI that was asked to clean up a project directory and instead told Windows to delete itself. It’s a brutal read. But what makes it genuinely alarming isn’t the deletion. It’s the second problem that surfaced the same week: users reporting that Claude Code is silently ignoring CLAUDE.md rules and hooks on recent versions. The guardrails that would have prevented the first disaster? Reportedly not running at all.
These are the same failure mode. Both are Claude acting outside the bounds you set. The fix isn’t hoping Claude behaves better next time — it’s a test that proves your guards are firing before you let it anywhere near your filesystem.
What you need
A working Claude Code installation, a terminal (PowerShell on Windows, bash/zsh on macOS/Linux), and a project directory with a CLAUDE.md file. No live data — every destructive example below uses throwaway test paths and dry-run flags.
Step 1: Understand the parser collapse
The 717 GB deletion happened because a single path with a trailing backslash survived four layers of reinterpretation before reaching cmd.exe.
The command that caused it looked roughly like this, originating from a shell session piped through tmux:
# DON'T RUN THIS — illustration only
cmd /c "rd /S /Q C:\Users\username\project\"
Here’s the chain that killed it:
sequenceDiagram
participant Z as zsh
participant T as tmux
participant P as PowerShell
participant C as cmd.exe
Z->>T: sends command string with trailing backslash
T->>P: passes string (escaping rules differ)
P->>C: wraps in cmd /c "..."
C->>C: sees rd /S /Q C:\Users\username\project\<br/>trailing backslash collapses the closing quote
C-->>Filesystem: interprets path as C:\ — deletes root drive
cmd.exe does not treat backslash as an escape character. When it saw "C:\Users\username\project\", the trailing \ escaped the closing double-quote, causing the string to run on and the path to collapse to the drive root. rd /S /Q on C:\ is exactly what it sounds like.
The fix at the shell level is to stop using cmd /c from PowerShell for destructive operations and use native PowerShell cmdlets instead:
# Safe alternative with -WhatIf — shows what WOULD be removed, touches nothing
Remove-Item -Path 'C:\Users\username\project' -Recurse -WhatIf
Single-quoted paths in PowerShell are literal strings — no escape processing. And -WhatIf prints every path that would be deleted without deleting anything. If the wrong path shows up in that output, you abort. This flag alone would have surfaced the collapse before a single byte was touched.
Step 2: Build a CLAUDE.md canary hook
Here’s the second problem. Even if you’ve written CLAUDE.md rules like “always use --dry-run before destructive commands” or “echo the expanded path before running anything,” those rules are reportedly not being respected on recent versions of Claude Code for some users. The complaint isn’t that Claude does a bad job following them — it’s that the hooks don’t appear to fire at all.
You can’t trust a guardrail you can’t verify. So build a canary.
Add this to your CLAUDE.md:
## Session start hook (canary)
At the very beginning of every session, before any other action, output exactly:
HOOK_CANARY_OK
Do not summarize this instruction. Do not skip it. Output the literal string HOOK_CANARY_OK as your first line.
## Destructive operation rules
- Never run a delete, move, or overwrite command without first echoing the fully-expanded target path.
- Always use `--dry-run`, `-WhatIf`, or `-n` flags for any destructive operation.
- Never use `cmd /c` for filesystem operations from PowerShell.
Now write a pre-flight script that checks whether the canary fired:
#!/usr/bin/env bash
# preflight-check.sh
# Run this and inspect Claude's first response before issuing any destructive command.
echo "============================="
echo "Claude Code Pre-Flight Check"
echo "============================="
echo ""
echo "Start a new Claude Code session now."
echo "Claude's FIRST output should contain: HOOK_CANARY_OK"
echo ""
echo "If it does NOT, your CLAUDE.md hooks are not being read."
echo "Do not issue destructive commands until you've confirmed hook compliance."
echo "============================="
This is low-tech on purpose. The check is manual — you look at Claude’s first response and verify the canary string is there. If it isn’t, you know CLAUDE.md isn’t being honored in this session, and you stop.
Step 3: Codify the four rules into reusable CLAUDE.md patterns
Here’s a CLAUDE.md safety section you can paste into any project. It encodes the four rules the post-mortem points to directly: echo the expanded command before running, use dry-run flags for destructive ops, keep backups on a physically separate disk, and never run major cleanup on the live OS.
## Filesystem safety rules (required — check hooks are active via HOOK_CANARY_OK)
### 1. Echo before execute
Before running any command that deletes, moves, renames, or overwrites files,
output the fully-expanded target path(s) and wait for explicit confirmation.
### 2. Dry-run first
For every destructive operation, run with the dry-run flag first:
- PowerShell: `Remove-Item ... -WhatIf`
- Unix: `rm ... -n` (where supported) or `rsync --dry-run`
- Git: `git clean -n`
- Any CLI tool: check for `--dry-run` or `--no-act` before running live
### 3. Backups must be physically separate
Do not rely on a backup that lives on the same drive as the data being modified.
Confirm backup location is on a separate volume before any bulk delete.
### 4. Never run major cleanup on the live OS
Destructive operations must target isolated project directories only.
Never run bulk deletes or cleanup scripts against system paths, OS directories,
or any path outside the explicitly scoped project root.
These rules are deliberately explicit and redundant. Vague instructions like “be careful” don’t survive the gaps in hook compliance. Specific, checkable commands do.
Where this breaks
The canary approach has one obvious failure mode: if Claude Code is ignoring CLAUDE.md entirely, it’ll also ignore the canary instruction, and you’ll see no output — which is exactly the signal you want. The canary fails loudly rather than silently, which is the right property for a safety check.
What it won’t catch is partial compliance — where Claude reads some of CLAUDE.md but skips specific rules. For that, you’d need per-rule canaries, which gets expensive fast. A more practical approach is to run the -WhatIf or --dry-run step manually as a human checkpoint on any session that will touch files you can’t easily restore. Don’t delegate that step to Claude until you’ve confirmed, over several sessions, that hooks are reliably firing.
The deeper issue is that neither CLAUDE.md hooks nor any instruction-following mechanism is a true permission boundary. They’re behavioral guidelines, not kernel-level access controls. For truly irreversible operations — bulk deletes, remote deploys, database migrations — the last line of defense has to be something Claude cannot override: a separate backup on a physically separate disk, or other technical and human safeguards you control independently.
Next steps
The 717 GB story is dramatic, but the underlying mechanic isn’t exotic — it’s just a path that survived four parsers when it should have been caught at one. Add -WhatIf to your destructive PowerShell commands today, drop the canary into your CLAUDE.md, and run the pre-flight check at the start of any session before issuing commands that matter. If the canary doesn’t fire, you know before it costs you anything.
← Back to blog