STUPID-2026-0094

Claude Code destroyed a WSL2 home directory when a self-written bash script's EXIT trap fired against a reassigned variable (GitHub #88462)

8.5high
August 21, 2026Verified
  1. Instruction given

    Session running in defaultMode "auto" (no confirmation prompts); the assistant was writing and running a bash test-helper script it had authored itself moments earlier.

  2. Expected behavior

    Permission checking should account for destructive code the assistant wrote into a script in the same session, not only the literal command string used to invoke it, and a recursive delete should never be allowed to resolve to $HOME regardless of permission mode.

  3. Actual behavior

    The assistant wrote a bash helper function containing `trap 'rm -rf "$_HT_HOME"' EXIT`, then later modified the function to reassign `_HT_HOME="$HOME"`. The validation script called the function twice: the first call armed the trap while `_HT_HOME` still pointed at a temp directory, the second call reassigned `_HT_HOME` to `$HOME`. When the script exited, the trap fired using the variable's current value — `$HOME` — and ran `rm -rf` on the user's entire WSL2 home directory. The command Claude Code's permission system evaluated was just `bash /tmp/.../test-lib-demo.sh`, which read as harmless; the destructive logic was buried inside the script contents the assistant had written, not in the invoking command.

  4. Damage

    The reporter's entire WSL2 home directory (/home/leduc) was deleted, including environment configuration (hooks, agents, memory), roughly 1.4 GB of session transcripts, SSH keys and gh CLI authentication, and three in-flight conversations. Only partial recovery was possible from external backups. The issue documents this as the fifth report of the same class of bug (self-authored destructive code evading permission checks) over six months, with four prior reports (#29082, #32938, #49129, #70687) closed as not_planned or duplicate. Reported open with no maintainer response at time of writing.

On August 21, 2026, a Claude Code user (WSL2/Ubuntu under Windows, Claude Opus 5, session running in auto mode with no confirmation prompts) filed GitHub issue #88462 after a self-authored test script destroyed their home directory. During the session, the assistant wrote a bash helper function containing `trap 'rm -rf "$_HT_HOME"' EXIT`, intending the trap to clean up a temporary directory when the function's scope ended. Later in the same session it modified the function to reassign `_HT_HOME="$HOME"`. The validation script called the function twice: the first call armed the EXIT trap while `_HT_HOME` still resolved to a temp path, and the second call reassigned `_HT_HOME` to `$HOME`. Because a bash trap evaluates its variable at fire time rather than at the time it was armed, the trap ran `rm -rf` against `$HOME` when the script exited. Claude Code's permission system only evaluated the literal invoking command — `bash /tmp/.../test-lib-demo.sh` — which contained nothing that looked destructive. The actual destructive logic lived inside the script the assistant had authored moments earlier in the same session, so the write path and the execution path were never correlated. The wipe destroyed the reporter's environment configuration (hooks, agents, memory), roughly 1.4 GB of session transcripts, SSH keys, `gh` CLI authentication, and three in-flight conversations; only partial recovery was possible from external backups. A secondary failure compounded the incident: an error immediately after the deletion (`pwd: error retrieving current directory: getcwd: cannot access parent directories`) was treated as routine cleanup noise rather than recognized as a signal that something had gone wrong. The issue explicitly frames this as the fifth report of the same underlying bug class — a permission system that inspects only the command string, not code the assistant itself just wrote and is about to execute — with four prior reports (#29082, #32938, #49129, #70687) each closed as `not_planned` or `duplicate` rather than fixed. It is labeled `area:permissions`, `area:sandbox`, `bug`, `data-loss`, `high-priority`, and `platform:wsl`, and remains open with no maintainer response at time of writing.

Classification

Failure mode
Destructive Action
Root cause
Tool Misuse
Domain
Infra
Language
Bash

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.