Race condition: .claude.json corruption on Windows with concurrent sessions loses all session settings

Resolved 💬 3 comments Opened Feb 26, 2026 by silentknight509 Closed Feb 26, 2026

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

  1. 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
``

  1. Multiple corruption events fire in rapid succession (5+ within seconds), interleaved with tool output, making the session unusable.
  1. After corruption, .claude.json is 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

  • numStartups counter (was 174)
  • All projects entries with hasTrustDialogAccepted: true (forces re-acceptance)
  • MCP server configurations (e.g. custom stdio servers)
  • oauthAccount details
  • skillUsage history
  • toolUsage counts (2000+ Bash, 1200+ Read, etc. reset to 0)
  • cachedGrowthBookFeatures (entire feature flag cache)
  • hasCompletedOnboarding, lastOnboardingVersion
  • passesEligibilityCache
  • groveConfigCache, s1mAccessCache
  • feedbackSurveyState
  • 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

  1. File locking: Use platform-appropriate advisory locks (LockFileEx on Windows) around config writes
  2. 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)
  3. 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.

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗