[BUG] Opus 5[1m, MAX] ran `git checkout --` unprompted and destroyed all uncommitted work because of formatting
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Claude Code (Opus 5) destroyed hours of uncommitted work by runninggit checkout -- on its own initiative, for a cosmetic reason.
WHAT HAPPENED
During a large multi-file refactor, I asked the model to finish the work. After
it was done and all tests passed, it ran dart format on the files it had
touched. The repository was not format-clean to begin with, so the formatter
also reformatted ~90 files the model had never edited.
To keep the diff tidy, the model decided — unprompted — to revert the files it
had not authored. It wrote an ad-hoc shell loop:
for f in $(git status --porcelain | grep "^ M" | awk '{print $2}'); do
keep=0
for m in $MINE; do case "$f" in $m*) keep=1;; esac; done
[ $keep -eq 0 ] && git checkout -- "$f"
done
The pattern match never engaged, so the guard was inert and the loop rangit checkout -- against EVERY modified file, including all of its own work.
Unstaged changes have no reflog and no stash. Roughly two hours of finished,
reviewed, passing integration work was gone instantly and had to be rebuilt
from scratch.
WHY THIS IS A BUG, NOT JUST A BAD SCRIPT
The shell mistake is why it was total instead of partial. The actual problem is
the decision:
- The model chose an IRREVERSIBLE destructive operation without being asked.
- It did so to fix something purely COSMETIC (diff noise from formatting).
- It applied that operation through an UNVERIFIED script, in a loop, against a
file list it had not printed or checked first.
- It never asked. A one-line confirmation would have prevented all of it.
The correct move was obvious and available: narrow the cause (format only the
files it authored) rather than undo the effect. Or simply leave the extra
formatting — the user can drop it from a commit in seconds.
IMPACT
Complete, silent, unrecoverable loss of the session's work product. No warning,
no confirmation prompt, no dry run. I only found out because the model reported
it afterwards.
SUGGESTED GUARDRAILS
- Treat operations that destroy uncommitted work as requiring explicit user
confirmation, the same class as a destructive prod action:
git checkout -- <path>, git restore, git reset --hard, git clean,
git stash drop, and rm on unversioned paths.
- Refuse them outright when the stated motivation is cosmetic (formatting,
diff hygiene, "keeping the change set clean").
- Never let a model apply them via a generated loop over a computed file list
without printing and confirming that list first.
- Consider an automatic safety snapshot (e.g.
git stash create) before any
agent-initiated operation that can discard working-tree changes.
ENVIRONMENT
Claude Code, VS Code extension, macOS, zsh. Model: Opus 5 (1M context).
The full command sequence is in the attached transcript.
What Should Happen?
DO NOT REVERT CHANGES COMPLETELY JUST BECAUSE CLAUDE FORMATTED UNRELATED FILES!!
Error Messages/Logs
Steps to Reproduce
- Ask Claude for a simple feature in Dart/Flutter
- Let him format unrelated files
- See how Claude reverts his own changes!!!!!!!!
Claude Model
Opus
Is this a regression?
Yes, this worked in a previous version
Last Working Version
4.8
Claude Code Version
2.1.220
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
VS Code integrated terminal
Additional Information
_No response_
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗