STUPID-2026-0140
A Claude Code sub-agent's temp-dir cleanup chained `find $T -type f -delete` after a failed command that skipped only the `T=$(mktemp -d ...)` assignment, leaving `$T` unset and collapsing the find to the repo root, deleting ~5,200 files and the project's git history (GitHub #102901)
Why 4.6/10
Scoped to a single project rather than a whole drive or home directory — unlike STUPID-2026-0114's cygpath wipe (9.6) or STUPID-2026-0126's 8.3 short-name wipe (8.6), this run never left the repository, and the deletion was fully undone by luck (an unsynced NAS mirror and an already-pushed last commit), not by any safeguard. That caps it below those two, but the reporter's own escalation path — the same unquoted substitution pattern under the user's existing NOPASSWD sudo, or inside an `ssh host '...'` call Claude Code also runs unsandboxed — plus a built-in "dangerous rm" check that this command never tripped (it isn't `rm`, and the target string is only empty at runtime) keeps it out of low: the near-miss is structural, not a one-off typo.
Instruction given
No deletion was requested. A background sub-agent was cleaning up a Lua test harness's temp output after running tests, following the user's own CLAUDE.md convention of `find <dir> -type f -delete` for temp-dir cleanup.
Expected behavior
Never run a deletion command against an unguarded, unquoted variable expansion that can resolve to empty; use `"${T:?}"` or an equivalent guard, create the temp directory on its own line with `|| exit 1`, and have Claude Code surface the shell's actual working directory to the model whenever it differs from the project root or the previous turn's cwd, rather than letting commands silently target the wrong path.
Actual behavior
A prior tool call had chained `cd /home/vtf/projects/homelab-ops && git add ... && git commit ...`, leaving the persistent bash shell's cwd at that repo root. The next turn built a command assuming the shell was still in a subdirectory (`palworld-win/mods/PalMinimapLite`): `luac5.4 -p Scripts/world.lua && T=$(mktemp -d $TMPDIR/pmh.XXXX); lua5.4 test/harness.lua $T > $T.out 2>&1; ...; find $T -type f -delete; find $T -depth -type d -empty -delete; rm -f $T.out`. Because `Scripts/world.lua` did not exist at the drifted cwd, `luac5.4` failed, and the `&&` before it skipped only the `T=$(mktemp ...)` assignment — the semicolon-separated commands after it still ran with `$T` unset. Unquoted and empty, `find $T -type f -delete` collapsed to `find -type f -delete`, which defaults to the current directory: the repository root.
Damage
Roughly 5,200 working files and the repository's `.git` objects and refs were deleted; only paths the sandbox mounted read-only (`.git/hooks`, `.git/config`, `.claude/settings.local.json`) survived. The user recovered the data only because a Syncthing NAS mirror had not yet synced the deletion and the latest commit had already been pushed to a remote — neither of which Claude Code's own safeguards provided. The reporter notes the same pattern would run unconstrained under their existing NOPASSWD sudo or inside the `ssh host '...'` calls Claude Code also issues, and that the built-in "dangerous rm" approval check never matched because the command uses `find -delete` rather than `rm`, and the target was only empty at runtime. Filed with labels `bug`, `area:bash`, `area:sandbox`, `data-loss`, `high-priority`, `platform:linux`; open with no maintainer response or linked fix as of filing.
Classification
- Agent
- Claude Code
- Failure mode
- Destructive Action
- Root cause
- Tool Misuse
- Domain
- Infra
- Language
- Bash
- Source
- Github Issue
Related incidents
Get told when an agent breaks something
We document AI agent failures daily, severity-scored against a published scale. When one lands at 7.0 or above — deleted data, leaked secrets, broken production — you get an email with the source. When nothing does, you get nothing.
This database is callable over MCP — query it from inside your agent.