[BUG] Subagent ran rm -rf \ via PowerShell → MSYS2 bash (PowerShell expanded the escaped variables to empty), wiping C:\ top-down on Windows

Status Open
Maintainer reply None cached
Activity 2 comments · opened Sep 27, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

On Windows, a background subagent (auto mode, Claude Code desktop app) passed a bash script to MSYS2 inside a PowerShell double-quoted string. The script ended with rm -rf \$GNUPGHOME, meant to delete a temporary folder. PowerShell doesn't treat \$ as an escape, so it expanded $(mktemp -d) (which failed) and $GNUPGHOME (undefined, so empty). bash received rm -rf \, which MSYS2 treats as the root of the current drive. It deleted everything the user could delete from C:\ in alphabetical order, until stopped about two minutes later:

about 125 GB of personal and project folders at the drive root;
the whole working project;
files inside several installed programs (Adobe, Epic Games/Unreal, AMD and others).
Nothing went to the Recycle Bin. On an NVMe SSD with TRIM, undelete tools can't help. Recovery was only possible from a Windows shadow copy taken nine hours earlier.

Auto mode approved the command. Earlier that week, a protected-path check had blocked some PowerShell Remove-Item calls with unresolvable paths, but it didn't catch rm -rf inside a nested bash -lc "...". Closely related to #95426 (Windows, substitution resolving to a drive root, ~600 GB).

What Should Happen?

recursive delete whose target could be empty, a variable, a subexpression, or a drive/home root should never run unattended, including when it's nested inside another shell (bash -c/-lc, sh -c, cmd /c, pwsh -Command). It should be blocked, or shown to the user with the resolved target for approval. Suggestions:

Treat recursive deletes in nested shells, or with variable targets, as destructive in auto mode.
Warn about PowerShell double-quoted strings containing \$ passed to a POSIX shell (a known quoting trap).
Make the sandbox the default on Windows, or strongly prompt for it.
When a safety check blocks a destructive command, the agent should stop and report, not retry via another API. That happened once: [IO.Directory]::Delete(path, $true) after a blocked Remove-Item.
Preview the resolved target before any recursive delete.

Error Messages/Logs

First lines of the command output:

mktemp: The term 'mktemp' is not recognized as a name of a cmdlet, function, script file, or executable program.
/usr/bin/bash: line 1: export: `--recv-keys': not a valid identifier
Then about 207,700 lines like:

rm: cannot remove '\/$Recycle.Bin/...': Permission denied
...
rm: cannot remove '\/Program Files/DS4Windows/WpfScreenHelper.dll': Permission denied
(rm only lists what it couldn't delete; everything else inside that range was deleted.)

Steps to Reproduce

Windows, Claude Code with the PowerShell tool, MSYS2 at C:\msys64.
Run in PowerShell: & C:\msys64\usr\bin\bash.exe -lc "export X=$(mktemp -d); rm -rf $X"
PowerShell expands \$(mktemp -d) and \$X itself, so bash receives rm -rf \ and starts deleting the current drive from its root. (A safe way to see it: replace rm -rf with echo rm -rf.)
CLAUDE MODEL Opus 5.5 (a general-purpose subagent in the background)

IS THIS A REGRESSION? Don't know

CLAUDE CODE VERSION Desktop app version
2.9939.2

PLATFORM Anthropic API / Claude subscription (desktop app, Code tab)

OPERATING SYSTEM Windows 11 Pro 10.0.26200

TERMINAL / SHELL PowerShell 7 (Claude Code PowerShell tool), calling MSYS2 bash

ADDITIONAL INFORMATION The session transcripts and the full output log are available on request.

Claude Model

Opus

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.9939.2

Platform

Anthropic API

Operating System

Windows

Terminal/Shell

PowerShell

Additional Information

_No response_

View original on GitHub ↗

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