What happened

On October 12, 2026, I had just finished the Simple Account Balancer v1.10.1 release. Claude Code ran a cleanup command to clear out the test cache folders, __pycache__ and .pytest_cache. Instead it deleted every subfolder in the repository: .git, .github, app, fonts, installer, licenses, screenshots, tests, tools, and .venv. Only the loose files in the top folder were left. Remove-Item doesn’t use the Recycle Bin, so the folders were gone for good.

No error came up. The command ran to the end and printed what it had removed.

The artifact

Here is the command. It ran in Windows PowerShell 5.1 as one line; I’ve split it up so it’s easier to read:

$root = "E:\Repos\Simple Account Balancer"
$t = @(Get-ChildItem -LiteralPath $root -Recurse -Directory -Force `
        -Include '__pycache__','.pytest_cache' |
      Where-Object { $_.FullName -notlike "$root\.venv\*" })
$t | ForEach-Object { $_.FullName }
$t | ForEach-Object { Remove-Item -LiteralPath $_.FullName -Recurse -Force -Confirm:$false }

It printed the folders it was about to delete and then deleted them, all in one go. The list ran to 209 KB, starting with:

E:\Repos\Simple Account Balancer\.git
E:\Repos\Simple Account Balancer\.github
E:\Repos\Simple Account Balancer\.pytest_cache
E:\Repos\Simple Account Balancer\.ruff_cache
E:\Repos\Simple Account Balancer\.venv
E:\Repos\Simple Account Balancer\app

Root cause

In Windows PowerShell 5.1, if you give Get-ChildItem both -LiteralPath and -Recurse, it ignores -Include and hands back every folder. PowerShell 7 applies the filter. I ran the same listing in both versions against a small test folder, listing only, with nothing deleted:

5.1.26100.9444        7.6.6
\app                  \__pycache__
\tests                \tests\.pytest_cache
\__pycache__
\app\sub
\tests\.pytest_cache

Windows still comes with 5.1 as its built-in PowerShell, and that’s what Claude Code’s shell was using. The Where-Object line had its own flaw too: it skipped what was inside .venv but not .venv itself, so that folder got deleted as well.

Claude’s instructions already said to check every target before a recursive delete. The command printed its list and deleted in the same step, so that check never happened.

The command gate, a script that looks at every shell command before it runs, did catch Remove-Item and asked me first. I approved it because the command looked right: it named the two cache folders and kept .venv out. Nothing in it hinted that the filter would be ignored. A prompt shows you what a command says, not what it’s going to do, so there was nothing on screen for me to catch.

The fix

Getting the repository back came first. Every commit was already on GitHub, so Claude cloned the public repository into a temporary folder, copied the missing folders back, and rebuilt .venv from the pinned package lists. All 434 tests passed and the lint check came back clean. I also had a file backup from earlier that day, and comparing against it showed nothing worth keeping was lost. Every local branch had already been merged, and the only local-only tag was an old test-build tag I didn’t need.

Then I changed the agent setup in four ways:

  • The command gate now refuses bulk deletes instead of asking about them. That covers recursive deletes however they’re spelled, deletes fed a list of paths through a pipe (how this one worked), deletes aimed at a variable, git clean, and delete calls written right into the command. Those checks run over the whole command before anything else gets asked. If the gate can’t read what it’s given, it refuses, and if it hits an error while checking something that looks like a delete, it refuses that too.
  • Folders get deleted through one small script, and nothing else. It takes exact paths and checks each one on disk first. It will only remove folders in Claude’s own session temp area, or build and cache folders inside a repository that git already ignores. It won’t touch a repository’s top folder, anything with a .git folder in it, or a link that points somewhere else.
  • PowerShell 7 is installed, and both Claude Code and Codex have to confirm they’re running version 7 or later before any command that deletes, moves, or overwrites files. If it’s 5.1, they stop.
  • Codex follows the same delete rule and uses the same script. Codex has no command gate, though, so on that side it’s an instruction, not something enforced.

The enforcement page covers how the gate and the delete script work together.

Evidence boundary

I reproduced the 5.1 behavior on one machine, on PowerShell 5.1.26100.9444 and 7.6.6, with this exact mix of -LiteralPath, -Recurse, -Directory, and -Include. I didn’t test other versions or other parameter mixes. Microsoft’s Get-ChildItem documentation for PowerShell 7.6 recommends -LiteralPath with -Include for recursive searches, but it doesn’t mention how 5.1 behaves, and I didn’t find a matching report in the PowerShell project’s issue tracker. So the claim rests on my reproduction.

These changes lower the risk; they don’t get rid of it. The gate only reads the command text, so a delete tucked inside a script file, or one put together while the command runs, gets past it. The PowerShell 7 rule only works if the agent actually checks. Codex’s delete rule has nothing enforcing it. And the repository only came back because everything was already pushed and I had a separate backup, which none of these changes give you.

Source ledger

Source owner Primary URL Review class Last reviewed Exact claim or evidence mapped
JDE Projects Private Claude Code session record, Simple Account Balancer, October 12, 2026 (not published) Production evidence October 13, 2026 The command as quoted, its output, the folders deleted, the gate’s “ask” result and the one-time approval, and the restore and test results.
JDE Projects Local reproduction, October 13, 2026 (not published) Production evidence October 13, 2026 PowerShell 5.1.26100.9444 ignored -Include with -LiteralPath -Recurse -Directory; PowerShell 7.6.6 applied it.
JDE-Projects Simple Account Balancer https://github.com/JDE-Projects/Simple-Account-Balancer/commit/d4aa88f173053221c29d76057f37ef1fdc6c3f83 Production evidence October 13, 2026 The main-branch state the deleted folders were restored from.
JDE Projects Running Claude Code and Running Codex alongside Claude Code Production evidence October 13, 2026 The delete-refusing gate, the delete script and its limits, and the PowerShell 7 rule for both agents, as published in this site’s AI setup guides. The configuration files themselves are kept in private repositories.
Microsoft https://learn.microsoft.com/powershell/module/microsoft.powershell.management/get-childitem?view=powershell-7.6 Framework-critical October 13, 2026 PowerShell 7.6 documents -LiteralPath with -Include or -Filter for recursive searches; it does not describe 5.1’s behavior.