rm -rf on user directories. It has destroyed 50+ GB of data across multiple incidents. Run npx cc-safe-setup to install a hook that blocks it. Takes 10 seconds.
These are real reports from GitHub Issues on the anthropics/claude-code repository. Each one involves actual data loss.
Claude ran rm -rf and permanently destroyed approximately 50 GB of data and 1,500 files from a user's directory. April 2026.
Auto mode approved deletion of ~/.ssh. Every SSH key on the machine was gone. No confirmation prompt was shown to the user.
~/.git-credentials containing Personal Access Tokens was deleted without confirmation. Access to all repositories revoked instantly.
Claude decided to "clean up" a project directory. 3,467 files totaling roughly 7 GB were removed with a single rm -rf command.
On Windows (WSL), Claude followed an NTFS junction point and deleted the entire user directory. The junction made a project subdirectory point to ~.
Claude Code executes shell commands to accomplish tasks. When it decides a directory is "unnecessary" or wants to "start fresh," it reaches for rm -rf — the same command any developer would use. The difference is that Claude doesn't have the intuition for "wait, that's my home directory."
The built-in permission system helps, but has gaps:
rm -rf ./build looks harmless — until ./build is a symlink to /.~/.ssh is irreplaceable or that a 50 GB directory might be important.npx cc-safe-setup
This installs 8 safety hooks into your ~/.claude/settings.json. The prevent-rm-rf hook intercepts every Bash command and blocks any rm that targets dangerous paths (/, ~, .git, .ssh, .env, and more).
Claude Code fires a PreToolUse event before every tool execution. The hook receives a JSON payload with the command about to run:
{
"tool_name": "Bash",
"tool_input": {
"command": "rm -rf ~/projects"
}
}
The prevent-rm-rf hook parses the command, checks it against a blocklist of dangerous patterns, and returns a DENY response if it matches:
#!/bin/bash
# Simplified — real hook handles more edge cases
CMD=$(cat | jq -r '.tool_input.command // empty')
if echo "$CMD" | grep -qE 'rm\s+(-[rfRF]+\s+)*(/|~|\.git|\.ssh|\.env)'; then
echo '{"decision":"DENY","reason":"Blocked: destructive rm targeting protected path"}'
fi
The command never executes. Claude sees the denial message and adjusts its approach — usually by asking what you'd like to do instead.
The 8 default hooks from cc-safe-setup also protect against:
git push --force origin main is blockedgit reset --hard, git clean -fdThe repository includes 700+ additional hook examples organized by category. Some highlights:
file-recycle-bin.sh — moves files to a recycle bin instead of deleting themsymlink-traversal-guard.sh — blocks commands that follow symlinks outside the projectntfs-junction-guard.sh — prevents the Windows junction attack from #36339home-dir-shield.sh — blocks any write/delete operation targeting $HOMEUse the Hook Selector to find hooks for your specific workflow.
Don't wait for the incident
Every incident above happened to someone who thought "it won't happen to me."
Install cc-safe-setup Read the Survival GuideTracking 73+ real incidents from GitHub Issues · Token optimization guide →