[BUG] Critical: git stash pop + reset --hard destroyed ~600 lines of new code and unrelated stash in worktree session
Status Open
Reported on v2.1.276
Maintainer reply None cached
Activity 0 comments · opened Sep 18, 2026
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?
What happened
- Session A (N4-4328) had uncommitted work: review.mjs (~260 lines), review.spec.mjs (~308 lines), edits to 4 files
- Session B (N4-3927) had an uncommitted stash with ~86 files under packages/workspace/src/
- Both sessions shared the same git repository (monorepo)
- In Session A, bare
git stash popwas issued twice, followed bygit reset --hard HEAD - Result: Session A's N4-4328 work was destroyed, and Session B's N4-3927 stash was also destroyed
Impact
- Primary loss: ~570 lines of new code (review.mjs, review.spec.mjs) + modifications to validate-key.mjs, validate-key.spec.mjs, key-vocabulary.json, package.json
- Secondary loss: ~86 uncommitted files under packages/workspace/src/ belonging to N4-3927 branch
- Recovery: 1161 unreachable commits exist in object database but are unrecoverable without manual hash identification
- Cost: Significant token spend to faithfully re-implement from documented spec
Root causes
- Bare
git stash popissued despite environment forbidding it — enforcement message came too late (post-pop) git reset --hard HEADwas not blocked or confirmed when uncommitted changes were present- No cross-session stash isolation — one session's mistakes destroyed another session's work
- Reflog was reset, eliminating recovery trail
Environment
- Tool: Claude Code CLI
- Session type: git worktree
- Isolation: enabled (--worktree-path set)
- Monorepo: shared git database across multiple concurrent worktrees/sessions
What Should Happen?
- Block bare
git stash popin worktree sessions before execution — not after it fails with a warning. Environment currently forbids it but enforcement arrives too late to prevent the pop. - Require explicit confirmation for
git reset --hardwhen uncommitted changes exist, with a warning about stash stack safety and cross-session risks. - Tag stash entries by session ID so one session's stash pop cannot silently destroy another session's uncommitted work.
- Preserve reflog even after reset so
git reflogcan show what was discarded.
Error Messages/Logs
Steps to Reproduce
- Start a Claude Code session in a git worktree with uncommitted changes
- Issue
git stash push -u -m "my-work"to stash changes from another session - Push a second stash:
git stash push -u -m "other-session-work"(simulates concurrent session) - Issue bare
git stash pop(without flags) — this pops the most recent stash - If unaware of stash depth, issue
git stash popagain without verifying the first pop succeeded - Run
git reset --hard HEADto discard any remaining working-tree changes - Run
git stash list— observe: both stashes and all uncommitted work are gone - Run
git fsck --unreachable— observe: orphaned commits still exist in object database
Claude Model
Sonnet (default)
Is this a regression?
Yes, this worked in a previous version
Last Working Version
_No response_
Claude Code Version
2.1.276 (Claude Code)
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
VS Code integrated terminal
Additional Information
_No response_