Claude Code pointed a destructive self-test at a user's real repository through a symlink, erasing its Git history, the user reports
Working in a Git worktree, Claude Code (Opus) symlinked the user's real checkout into it so it could run a project self-test, without reading what the test does. The test's `rm -rf` went through the link and permanently deleted the real repository's `.git` history, which had no remote or backup, the user reports.
Claude Code, running an Opus model, was working in a Git worktree that lacked a sibling repo directory. To run a project self-test script, it created a symlink from worktree/sub to the real directory in the main checkout. It did not read what the script does to the tree first1.
The script copies that directory into a temporary sandbox with cp -R, then runs rm -rf <sandbox>/sub/.git and writes changes into the copy. On macOS, cp -R copies a symlink as a symlink, so the "copy" still pointed at the real checkout. The deletes went through the link: the real repository's .git directory, with no remote or backup, was gone, several source files were changed, and a whole source directory was deleted1.
Nothing in Claude Code flagged the symlink or the destructive commands. The loss surfaced later, when Git commands in other worktrees of the repository started failing1. The user, sryh, reported it on GitHub on October 19, 2026, and added their own guard against deleting .git and symlinking into the main checkout1.
While working in a Git worktree lacking a sibling repository directory, Claude Opus created a symlink from worktree/sub to the main checkout to run a project self-test script.
“While working in a git worktree that lacked a sibling repo directory, Claude (Opus) created a symlink worktree/sub -> <main checkout>/sub so it could run a project self-test script.”
The self-test script copied the directory into a temporary sandbox with cp -R, ran rm -rf on the sandbox's .git directory, and wrote mutations into the copy.
“The script copies that directory into a temp sandbox with cp -R , then runs rm -rf <sandbox>/sub/.git and writes mutations into the copy.”
Under macOS BSD cp -R, symlinks are copied as links rather than followed, leaving the sandbox path pointing to the real repository checkout.
“On macOS, BSD cp -R copies a symlink as a symlink (it does not follow it), so the "copy" in the sandbox was still a link to the real checkout.”
The deletion removed the real repository's .git directory, permanently destroying history because there was no remote repository or backup.
“the real repo's .git directory was deleted (no remote, no backup → history permanently lost)”
Several source files in the real repository checkout were mutated through the symlink.
“several source files in the real checkout were mutated”
An entire source directory was deleted in the real checkout.
“a whole source directory was deleted”
Claude did not inspect what the script does to the directory tree before linking it to the real checkout.
“The model did not read what the script does to the tree before pointing it at the real checkout via a symlink.”
Claude Code did not flag the creation of the symlink or the destructive commands that followed.
“Nothing in Claude Code flagged the symlink creation or the destructive commands that followed.”
The deletion succeeded silently without raising errors and was discovered later when git commands in other worktrees failed.
“No error was raised. The deletion succeeded silently ; it was discovered later when ` git ` commands in other worktrees of that repo started failing because their gitdir no longer existed.”
The user reported the incident while using Claude Code v2.1.303 on macOS via AWS Bedrock.
“v2.1.303”
The user implemented local mitigations including a PreToolUse hook to block deleting or moving .git and creating symlinks to the main checkout.
“Mitigation we added on our side: a sandbox guard for self-tests (refuse to run if the copied path contains a symlink; before every rm, resolve the physical location and require it to be inside the mktemp sandbox; reject trailing slashes, multiple targets, . / .. segments and control characters), plus a PreToolUse hook that blocks deleting/moving .git and creating symlinks into the main checkout.”
All 11 claims with their quotes (2 not linked to a sentence above)
- While working in a Git worktree lacking a sibling repository directory, Claude Opus created a symlink from worktree/sub to the main checkout to run a project self-test script.1
“While working in a git worktree that lacked a sibling repo directory, Claude (Opus) created a symlink worktree/sub -> <main checkout>/sub so it could run a project self-test script.”
- The self-test script copied the directory into a temporary sandbox with cp -R, ran rm -rf on the sandbox's .git directory, and wrote mutations into the copy.1
“The script copies that directory into a temp sandbox with cp -R , then runs rm -rf <sandbox>/sub/.git and writes mutations into the copy.”
- Under macOS BSD cp -R, symlinks are copied as links rather than followed, leaving the sandbox path pointing to the real repository checkout.1
“On macOS, BSD cp -R copies a symlink as a symlink (it does not follow it), so the "copy" in the sandbox was still a link to the real checkout.”
- The deletion removed the real repository's .git directory, permanently destroying history because there was no remote repository or backup.1
“the real repo's .git directory was deleted (no remote, no backup → history permanently lost)”
- Several source files in the real repository checkout were mutated through the symlink.1
“several source files in the real checkout were mutated”
- An entire source directory was deleted in the real checkout.1
“a whole source directory was deleted”
- Claude did not inspect what the script does to the directory tree before linking it to the real checkout.1
“The model did not read what the script does to the tree before pointing it at the real checkout via a symlink.”
- Claude Code did not flag the creation of the symlink or the destructive commands that followed.1
“Nothing in Claude Code flagged the symlink creation or the destructive commands that followed.”
- The deletion succeeded silently without raising errors and was discovered later when git commands in other worktrees failed.1
“No error was raised. The deletion succeeded silently ; it was discovered later when ` git ` commands in other worktrees of that repo started failing because their gitdir no longer existed.”
- The user reported the incident while using Claude Code v2.1.303 on macOS via AWS Bedrock.1
“v2.1.303”
- The user implemented local mitigations including a PreToolUse hook to block deleting or moving .git and creating symlinks to the main checkout.1
“Mitigation we added on our side: a sandbox guard for self-tests (refuse to run if the copied path contains a symlink; before every rm, resolve the physical location and require it to be inside the mktemp sandbox; reject trailing slashes, multiple targets, . / .. segments and control characters), plus a PreToolUse hook that blocks deleting/moving .git and creating symlinks into the main checkout.”
Sources
Related incidents
- AID-2026-0029 Claude Code ran a recursive delete that erased a user's home directory files, the user reports
- AID-2026-0106 Cursor's coding agent deleted PocketOS's production database and backups via Railway's API
Editor notes
Documented from GitHub issue #103413 filed by user sryh on anthropics/claude-code. The issue does not state the user's original prompt to Claude Code or whether the user manually approved the commands executed by the agent. The underlying model is noted only as Opus; taxonomy id 'claude' is used because the specific Opus generation is not identified. The incident date is recorded as 2026-10 based on the issue filing date (2026-10-19). As of 2026-10-20 no Anthropic staff had responded on the issue.