Concurrent sessions clobber ~/.claude.json, reverting hasTrustDialogAccepted and other per-project state

Open 💬 1 comment Opened Jul 2, 2026 by KingMob

Summary

When multiple interactive claude CLI sessions run concurrently, they clobber each other's writes to the single shared ~/.claude.json. The most visible casualty is workspace trust: projects["<path>"].hasTrustDialogAccepted silently reverts to false after the user has accepted the trust dialog, so on the next launch Claude prints Ignoring N permissions.allow entries ... this workspace has not been trusted and re-prompts for everything. Other per-project state is lost the same way.

This appears to be the same underlying defect as the (now-closed) reports linked below, but it is still reproducible on the current release, so I'm filing a fresh, self-contained report with live evidence and a concrete request to reopen/track.

Environment

  • Claude Code 2.1.198
  • macOS 26.4.1 (build 25E253), Apple Silicon
  • ~13 concurrent interactive claude CLI sessions (plus the VS Code extension and desktop app), all sharing one ~/.claude.json
  • ~/.claude.json is a single ~409 KB file with 164 projects entries

What happens

  1. Accept the workspace trust dialog for a project. The dialog stops appearing (the running session remembers it in memory).
  2. On disk, projects["<that path>"].hasTrustDialogAccepted is still — or soon becomes again — false.
  3. A later launch in that directory ignores permissions.allow and permissions.additionalDirectories from .claude/settings.json and re-prompts.

Evidence of the race (not a path-mismatch bug)

  • The workspace paths contain no symlinks; the projects key matches cwd exactly, so this is not the symlinked-config case.
  • Before intervening, 107 of 164 project keys read hasTrustDialogAccepted: false despite the user having accepted trust in many of them; only a couple held true.
  • I set all 164 keys to true in one atomic write and verified 0 remained false on disk.
  • ~2 minutes later, with the other sessions still running, the file had grown to 165 keys (a session added a new project) and 1 key had already reverted to false — a lost update captured in the act.

Likely mechanism

~/.claude.json mixes two very different kinds of data:

  • Rarely-changing user config — MCP servers, hasTrustDialogAccepted, onboarding state.
  • High-frequency runtime state — e.g. toolUsage counters that are updated on essentially every tool call, plus caches.

Because the runtime state is written constantly, each session performs a whole-file read-modify-write from its in-memory copy very frequently. A session that read the file at startup (with trust = false) and never touched the trust dialog will, on its next flush, rewrite the entire file and overwrite the true value another session just persisted. Trust is especially vulnerable because it is written once per session and never refreshed mid-session, so a stale in-memory copy always wins the next flush.

Impact

  • Workspace trust never reliably persists across a fleet of concurrent sessions.
  • permissions.allow / permissions.additionalDirectories are repeatedly ignored, so the permission allowlist is effectively non-functional and users are re-prompted constantly.
  • Other per-project settings written by one session are silently discarded by others.

Related (closed) reports

These describe the same class of defect and were closed without a shipped fix; this is still reproducible on 2.1.198:

  • #28829 — Critical regression: .claude.json corruption from concurrent sessions
  • #28966 — Configuration file (.claude.json) repeatedly corrupts during normal operation
  • #29036 — Race condition: .claude.json corruption on Windows with concurrent sessions
  • #36403 — Trust dialog acceptance not persisted to .claude.json
  • #28506 — --dangerously-skip-permissions does not bypass the workspace trust prompt

Suggested fixes (in order of preference)

  1. Separate ephemeral runtime state (toolUsage, caches, feature flags) from user config so ~/.claude.json is written rarely — dramatically shrinking the clobber window for trust and settings.
  2. Merge on write — re-read the current file and merge per-key just before writing (or patch only the changed keys) instead of rewriting the whole in-memory snapshot, so concurrent sessions don't overwrite each other's fields.
  3. Serialize writes with a file lock so a partial/stale write can never truncate or overwrite a newer one.

Happy to provide additional diagnostics from the affected machine.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗