Race condition: .claude.json corruption on Windows with concurrent sessions loses all session settings
Bug Description
Running multiple Claude Code windows simultaneously causes repeated .claude.json corruption due to concurrent writes without file locking. Every corruption event resets the file to a minimal stub, losing all accumulated session settings.
Environment
- Claude Code version: 2.1.59
- OS: Windows 11 Home 10.0.26200
- Shell: Git Bash
- Platform: win32
Symptoms
- Error floods the terminal during normal operation:
````
Claude configuration file at C:\Users\Shane\.claude.json is corrupted: JSON Parse error: Unexpected EOF
The corrupted file has been backed up to: C:\Users\Shane\.claude\backups\.claude.json.corrupted.XXXXX
- Multiple corruption events fire in rapid succession (5+ within seconds), interleaved with tool output, making the session unusable.
- After corruption,
.claude.jsonis replaced with a minimal ~850 byte stub containing only basic fields (tipsHistory,clientDataCache,userID,toolUsage). The full config (~12KB) is lost.
What is lost on each corruption
numStartupscounter (was 174)- All
projectsentries withhasTrustDialogAccepted: true(forces re-acceptance) - MCP server configurations (e.g. custom stdio servers)
oauthAccountdetailsskillUsagehistorytoolUsagecounts (2000+ Bash, 1200+ Read, etc. reset to 0)cachedGrowthBookFeatures(entire feature flag cache)hasCompletedOnboarding,lastOnboardingVersionpassesEligibilityCachegroveConfigCache,s1mAccessCachefeedbackSurveyState- All other accumulated session state
Evidence from backup directory
Over 6 days, 304 backup files accumulated in ~/.claude/backups/:
| Date | Corrupted files | Size (full config) |
|------|----------------|-------------------|
| Feb 20 | 1 | 10,498 bytes |
| Feb 21 | 1 | 11,056 bytes |
| Feb 24 | 3 | 12,100 bytes |
| Feb 25 | 4 | 12,524-12,610 bytes |
| Feb 26 | 6+ (rapid fire) | 12,611 bytes |
The corrupted backups are actually valid JSON containing the full config. The "corruption" is in the live file (truncated mid-write), not the backup.
Root cause
The atomic write pattern (write to .tmp, rename to target) fails on Windows when multiple Claude Code processes contend for the same file. Windows rename() returns EPERM if the target file handle is held by another process, breaking atomicity and leaving a truncated file on disk.
This is exacerbated by .claude.json serving as both:
- User configuration (MCP servers, project trust, onboarding) - rarely changes
- Runtime state (tool usage counts, feature flags, timestamps) - changes on every tool call
Every tool call in every window triggers a write to the same file, maximizing contention.
Impact
- Users running 2+ Claude Code windows (a common workflow) lose all session settings repeatedly
- Forces single-window workflow as a workaround, significantly reducing productivity
- Trust dialogs must be re-accepted after every corruption event
- MCP server configs must be manually restored
Suggested fixes
- File locking: Use platform-appropriate advisory locks (
LockFileExon Windows) around config writes - Separate runtime state from user config: Move frequently-written ephemeral data (tool counts, feature flag caches, timestamps) to a separate file from user-facing config (MCP servers, project trust, onboarding)
- Retry with backoff on EPERM: If rename fails due to another process holding the handle, retry instead of leaving a truncated file
Related issues
This has been reported multiple times:
- #28847, #28829, #28842, #28806, #28813, #26717, #15608
All prior reports identified the same root cause. None have been resolved.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗