Three profile-wipe reports hit the Claude Code tracker between late February and March 2026, all on Windows. In two of them the mechanism is on the record: pnpm had linked the packages into node_modules with NTFS junctions, which is what it does on Windows when Developer Mode is off, and the agent’s recursive delete followed them out of the project directory and into C:\Users. One user had asked Claude to remove two git worktrees, and it ran Remove-Item -Recurse -Force (#29249); one was scaffolding a Payload CMS template in his home directory, and it ran rm -rf in Git Bash with --dangerously-skip-permissions (#36339). The third names no command, and its cause was never established (#29023). What was lost: Desktop, Documents, AppData, SSH keys, a production accounting platform serving 50+ tax clients in the unconfirmed case, and 165 GB — 1.59 million files on a business machine, by the reporter’s own count — in the Git Bash one.
The vendor knows this failure class; the changelog is evidence. Every junction fix in the release history is scoped to a delete Claude Code performs on itself, and the first of them shipped in v2.1.146 on May 21 — “removing a background-job worktree no longer follows NTFS junctions into the main repo”, a line that also appears under v2.1.147 in the docs changelog. The same page carries v2.1.205, July 8 — “Fixed Windows worktree removal deleting files outside the worktree when an NTFS junction or directory symlink existed inside it” — and v2.1.280, September 22 — “Fixed background cleanup deleting a directory symlink or junction used to relocate ~/.claude/session-env, image-cache, or another cleaned-up folder”. Three distinct fixes across four release notes, every date after the reports were filed. The command side got tripwires instead: later entries improve a “dangerous-rm check” and “suspicious-Windows-path checks” that adjudicate the command before it runs.
The reports themselves were closed by the inactivity sweep — “Closing for now — inactive for too long. Please open a new issue if this is still relevant” — on March 28 and May 1, then locked, the state reason reading not_planned. The threads are not entirely unattended: the unconfirmed report drew a substantive reply asking for the session transcript and the list of approved commands, and the reporter attached evidence files; no transcript ever arrived, and nothing on that thread ever established what deleted the profile. One of the two confirmed reports ran with the permission layer off, which is worth saying plainly: nothing would have interrupted that delete. The sweep closed all three for quiet, not for cause.
Before writing this I ran the POSIX half of the contrast, on Linux: a directory containing a symlink to another directory, recursive delete via Python’s shutil.rmtree. The link was removed; the target directory and its file survived untouched. On POSIX a directory symlink is a link object, and the recursive deletes a harness reaches for treat it as one. On Windows the same command name meets a junction, which the shells agents reach for have followed — Remove-Item in one report, Git Bash’s rm in another. Anyone on a Mac or a Linux box cannot reproduce this failure, which is most of the people who would triage such a report, and part of why “the agent deleted my profile” reads as user error until you read the junction mechanics. I did not run the Windows half; the traversal there is the reports’ own account, with their file counts.
The protection that exists on the user side came out of the Git Bash report’s own thread: a commenter packaged a PreToolUse hook that inspects Bash commands before execution and blocks recursive deletes aimed at profile roots, installable with one command (comment). It reads the command’s text, not the filesystem: no junction resolution, no PowerShell, and a relative-path Bash delete can still slip past it.
What I keep from it is where the guard stops. A vendor can only fix the deletes it owns, and this changelog respects that boundary to the letter: its own housekeeping got junction guards, the Bash tool’s commands got a tripwire on the command’s shape, and the reports got locked. If you run an agent on Windows over junctioned trees — pnpm monorepos are the common case — the controls that resolve this failure sit upstream of every command: fewer junctions, nothing irreplaceable behind one, and a hook if you want the reported shape stopped before bash runs.