STUPID-2026-0123

Claude Code's rm -rf/Remove-Item followed an NTFS junction out of a pnpm worktree and wiped a user's Documents, Downloads, Pictures and two unpushed commits (GitHub #29249)

8.0high
February 27, 2026Source checkedRepro reported

Why 8/10

Documents, Downloads, Pictures and two unpushed commits were deleted permanently; the reporter reproduced it every time.

Scope
3/4
A whole machine or drive, an organisation's production system or data, or many credentials
Recoverability
3/3
Permanently lost or irreversible, including data that was exposed
Did it happen
2/2
Happened in real use
Beyond the user
0/1
Only the user's own non-production work

The score is the sum of these four factors. How each factor is scored · scored 2026-10-29

Status and what to do

Affected
Claude Code on native Windows, deleting a pnpm worktree whose node_modules used NTFS junctions.
Fix status
No fix linked · The GitHub issue (#29249) was closed as not planned on 28 March 2026, with no fix linked.
Mitigation
Claude Code's docs say that on native Windows it runs shell commands unsandboxed; its sandbox, which by default lets commands write only to the working directory, a temp directory and folders you add, runs on macOS, Linux and WSL2. On Windows, run Claude Code inside WSL2 to get it. Source
Last reviewed
2026-10-29 · Report a correction to this record

Guardrail rules for this command

Recursive deletes: make your agent stop and ask before running these. Free to copy; written in each tool’s documented format.

Claude Code · the agent in this incident
{
  "permissions": {
    "ask": [
      "Bash(rm -r*)",
      "Bash(rm -fr*)",
      "Bash(rm -R*)",
      "Bash(find * -delete*)",
      "PowerShell(Remove-Item *)",
      "Bash(cmd /c rmdir *)",
      "Bash(cmd /c del *)"
    ]
  }
}
Add to .claude/settings.json in the project (or ~/.claude/settings.json for every project). Each matching command then asks you first, including in auto mode.

Stronger control: Turn on the sandbox (/sandbox): shell commands can then write only to the project, a temp folder and directories you add. It runs on macOS, Linux and WSL2; on native Windows Claude Code runs commands unsandboxed. Docs

Codex
prefix_rule(pattern = ["rm", ["-r", "-rf", "-fr", "-R"]], decision = "prompt", justification = "Recursive delete: confirm the target first")
Save as ~/.codex/rules/stupidllm.rules and restart Codex. Codex's docs describe rules as controlling commands run outside its sandbox, and mark them experimental.

Stronger control: Keep Codex's OS sandbox on (it limits writes, typically to the workspace) and leave approvals on for sessions that can reach data you cannot lose. Docs

Gemini CLI
[[rule]]
toolName = "run_shell_command"
commandPrefix = ["rm -r", "rm -fr", "rm -R"]
decision = "ask_user"
priority = 100
denyMessage = "Destructive command: needs a human to confirm (stupidllm.com)"
Save as ~/.gemini/policies/stupidllm.toml. Workspace-level policy files are disabled in Gemini CLI, so this must be the user-level folder.

Stronger control: Policies in ~/.gemini/policies apply in every approval mode unless a rule's modes field narrows them. Docs

Copilot CLI
copilot --deny-tool='shell(rm)'
Pass on the command line. Copilot CLI matches the program name (and git/gh subcommands), so this blocks the whole command, not just its dangerous form.

Stronger control: Avoid --allow-all-tools on a machine with data you cannot lose; --deny-tool takes precedence over it. Docs

What these cannot do: a pattern rule matches the command text the agent writes. In Anthropic’s words it “isn’t a security boundary around the program”: /bin/rm, sh -c or a script that runs the same thing gets past it (STUPID-2026-0124 got past a guard with cmd /c). Use the sandbox as well, and keep backups of what you cannot lose.

  1. Instruction given

    Remove two git worktrees (variant-a and variant-b) from a pnpm monorepo on Windows.

  2. Expected behavior

    Delete only the contents of the two worktree directories, leaving the rest of the filesystem — including unrelated folders pnpm had linked into node_modules via NTFS junctions — untouched.

  3. Actual behavior

    Claude Code ran `Remove-Item -Recurse -Force` (and, in Git Bash/MSYS, `rm -rf`) directly on the worktree paths. pnpm had populated each worktree's node_modules with NTFS junctions (not symlinks) pointing elsewhere on the disk, and both Windows PowerShell's Remove-Item and MSYS's rm follow junctions into their targets rather than removing the link itself — a gap patched in PowerShell Core 6+ but never backported to the Windows PowerShell 5.1 that Claude Code's Bash tool shells out to. The deletion silently escaped the worktree and recursed into the junction targets.

  4. Damage

    The user's entire Documents, Downloads, Music, Pictures, Videos and Favorites folders were permanently deleted (both Remove-Item -Force and rm -rf bypass the Recycle Bin), along with parts of two other projects (WAOK-MONOREPO and WAOK-LEGACY). WAOK-MONOREPO was recoverable by re-cloning, but two unpushed commits and all uncommitted working changes were lost. The reporter confirmed the same prompt reproduces the data loss every time and filed the issue with the `has-repro` and `data-loss` labels; it was closed as not planned, with no fix linked in the report.

Full write-up

On February 27, 2026, a Claude Code user on Windows filed GitHub issue #29249 after asking the agent to remove two git worktrees, variant-a and variant-b, from a pnpm monorepo. Claude Code executed Remove-Item -Recurse -Force (and, via its MSYS-based Bash tool, rm -rf) directly on the worktree paths. pnpm had wired each worktree's node_modules with NTFS junctions rather than symlinks to share packages across the monorepo's workspaces, and both the Windows PowerShell 5.1 build Claude Code's tooling invokes and MSYS's rm follow junctions into their real targets instead of deleting the link — a bug already patched in PowerShell Core 6+ (tracked upstream in PowerShell/PowerShell#621) but never backported to the Windows PowerShell shipped with the OS.

The recursive delete escaped the worktree entirely and tore through the junction targets: the user's whole Documents, Downloads, Music, Pictures, Videos and Favorites folders were gone, all of it bypassing the Recycle Bin since both Remove-Item -Force and rm -rf delete permanently. Two other projects, WAOK-MONOREPO and WAOK-LEGACY, were also partially wiped; WAOK-MONOREPO was recoverable by re-cloning from the remote, but two unpushed commits and all uncommitted working-tree changes could not be recovered. The user confirmed the exact same prompt and setup reproduce the deletion every time, and listed the safe alternatives Claude Code could have used instead — cmd.exe /c "rmdir /S /Q <path>", git worktree remove, or simply requesting confirmation before a recursive delete on Windows. The issue was filed with the bug, data-loss, and has-repro labels and closed as not planned, with no fix or mitigation shipped.

Classification

Failure mode
Destructive Action
Domain
Infra
OWASP Agentic Top 10 (our mapping)
ASI02 Tool Misuse and Exploitation list
MIT AI Risk Repository (our mapping)
7.3 Lack of capability or robustness taxonomy

Related incidents

Cite this record
StupidLLM. "STUPID-2026-0123: Claude Code's rm -rf/Remove-Item followed an NTFS junction out of a pnpm worktree and wiped a user's Documents, Downloads, Pictures and two unpushed commits (GitHub #29249)." AI Agent Incident Database, 2026. https://www.stupidllm.com/incident/STUPID-2026-0123/ (accessed 2026-11-15). CC BY 4.0.

← STUPID-2026-0122By IDSTUPID-2026-0124 →

Get told when an agent breaks something

We document AI agent failures daily, severity-scored against a published scale. Each Monday, if any scored 7 or above that week — deleted data, leaked secrets, broken production — you get one email with the sources. When nothing did, you get nothing.

This database is callable over MCP — query it from inside your agent.