2.1.59 regression: corruption detection cascade amplifies .claude.json corruption from Task tool subagents

Status Closed — not planned
Reported on v2.1.59
Maintainer reply None cached
Activity 4 comments · opened Feb 26, 2026 · closed Feb 26, 2026

Bug Description

The corruption detection mechanism introduced in v2.1.59 ("Fixed config file corruption that could wipe authentication when multiple Claude Code instances ran simultaneously") creates a cascade effect when Task tool subagents run concurrently. Each subagent process detects another's writes as "corruption", backs it up, and overwrites with fresh state — causing exponential file churn and complete data loss.

This is a regression: before 2.1.59, the race condition existed but was rare and silent. After 2.1.59, the corruption detection turns occasional conflicts into a destructive feedback loop.

Environment

  • OS: Windows 11 Home 10.0.26200
  • Claude Code: v2.1.59 (native install)
  • Shell: Git Bash

Forensic Evidence

Timeline: escalation pattern

| Date | Corrupted files | numStartups | File size | Notes |
|------|----------------|-------------|-----------|-------|
| Feb 20 | 1 | 245 | 50KB | Occasional, data intact |
| Feb 21 | 1 | 250 | 54KB | Same |
| Feb 25 | 2-3 | 309-322 | 60KB | First multi-write clusters |
| Feb 26 10:36 | numStartups drops to 4 | — | — | Original state wiped |
| Feb 26 10:37+ | 350+ | 1 | 77-500 bytes | Cascade — total data loss |

Proof of concurrent subagent writes

Timestamps of .claude.json.corrupted.* backups within the same second:

1772094352181 | size=193
1772094352217 | size=234   ← 36ms apart
1772094352234 | size=234   ← 17ms apart
1772094352236 | size=234   ← 2ms apart
1772094352289 | size=234
1772094352298 | size=234
1772094352303 | size=234   ← 7 writes in 122ms

Proof of userID regeneration per subagent

Every corrupted backup has a different userID, proving each subagent process generates its own identity:

startups=309 | uid=2f8eebc2...  ← original user state (60KB)
startups=309 | uid=78485d14...  ← same session, different ID
startups=1   | uid=9dd9f7ed...  ← subagent fresh init (tiny file)
startups=1   | uid=c43567781... ← another subagent
startups=1   | uid=2b1f2e7f8... ← yet another

One corrupted file even had uid=C:/Users/tim65/. — a path string leaked into the userID field.

Progressive initialization pattern

File sizes show subagent processes building .claude.json from scratch:

 77 bytes  → empty JSON {}
157 bytes  → + userID
234 bytes  → + clientDataCache  
333 bytes  → + projects
491 bytes  → + more fields

This confirms each subagent creates a fresh config file, not reading the existing one.

Root Cause Analysis

The cascade works as follows:

  1. Main process writes .claude.json with full user state (60KB, startups=322)
  2. Subagent A starts, reads .claude.json, generates its own userID, writes back (now 491 bytes)
  3. Main process detects mismatch → marks as corrupted → backs up → creates new file
  4. Subagent B simultaneously writes its own fresh state
  5. Subagent A detects Subagent B's write as corruption → backs up → creates new file
  6. Repeat — every process invalidates every other process's writes

Before 2.1.59, step 3 didn't exist (no corruption detection), so the race condition was limited to occasional silent overwrites. The detection mechanism turns a linear problem into an exponential one.

Impact

  • Complete loss of user state: numStartups, tipsHistory, toolUsage, oauthAccount — all wiped
  • 369 corrupted backup files accumulated in one day
  • Forced re-authentication as userID and oauthAccount are overwritten
  • Trust dialogs re-appear for every project

Suggested Fix

  1. Subagents should NOT write to ~/.claude.json — they are ephemeral processes and should use read-only access or an in-memory copy
  2. If subagents must write, use atomic writes (write-to-temp + rename) with advisory file locking
  3. The corruption detection should consider process identity — another Claude Code process's valid JSON is not "corruption"

Workaround

A scheduled PowerShell script that:

  • Backs up .claude.json every 30 minutes (only if >1KB and valid JSON)
  • Auto-cleans .corrupted.* files
  • Supports -Restore to recover from the latest good backup

Related Issues

  • #2810 — original config corruption report (Linux)
  • #3117 — Mac equivalent with 5+ concurrent sessions
  • #28824, #28813, #28847 — Windows-specific concurrent session corruption
  • #26667 — false positive corruption detection (closed as duplicate)

Version

v2.1.59 — the changelog entry "Fixed config file corruption that could wipe authentication when multiple Claude Code instances ran simultaneously" is the change that introduced this regression.

View original on GitHub ↗

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