.claude.json workspace trust wiped by concurrent writes; path normalization stores duplicate false entries (Windows)

Resolved 💬 2 comments Opened Jun 4, 2026 by brownm09 Closed Jun 8, 2026

Summary

Two bugs cause workspace trust to be lost periodically, blocking scheduled routines from
executing even with bypassPermissions mode enabled. Both are confirmed from app logs on
Windows 11 with Claude Code Desktop (version 1.8555.2.0).

---

Bug 1: Concurrent writes corrupt .claude.json, wiping all trust state

Observed in: %APPDATA%\Claude\logs\main1.log (2026-05-24)

When multiple sessions start simultaneously (e.g., several scheduled routines fire at app
startup), saveWorkspaceTrust and checkWorkspaceTrustUncached race to read/write
C:\Users\<user>\.claude.json. The race truncates the file, producing empty or partial JSON.

Log evidence:

[error] Failed to parse config file C:\Users\brown\.claude.json: Unexpected end of JSON input
  at ua.checkWorkspaceTrustUncached (…index.js:2510:19666)
  at async ua.startSession (…index.js:2516:9083)

[error] Cannot start session: workspace C:\Users\brown\Git\dev-env is not trusted

[error] Failed to parse config file C:\Users\brown\.claude.json: Unexpected end of JSON input
  at ua.saveWorkspaceTrust (…index.js:2510:19736)

After corruption, all workspaces must be individually re-trusted — the app has no
mechanism to recover or re-seed trust from a backup. Scheduled routines that fire before
the user interactively re-approves fail silently with no session output.

Expected: saveWorkspaceTrust should use atomic write (write-to-temp + rename) or
advisory file locking to prevent truncation under concurrent access.

---

Bug 2: Path normalization creates duplicate entries — forward-slash variant has hasTrustDialogAccepted: false

On Windows, the same workspace can be stored under both normalized forms:

  • C:\Users\brown\Git\dev-envhasTrustDialogAccepted: true
  • C:/Users/brown/Git/dev-envhasTrustDialogAccepted: false

When the app resolves a path using forward slashes and finds the false entry, it re-prompts
even though the user already approved the backslash-form entry. This is intermittent — it
depends on which form checkWorkspaceTrustUncached uses to build its lookup key.

Observed .claude.json state (redacted):

{
  "projects": {
    "C:\Users\brown\Git\dev-env":         { "hasTrustDialogAccepted": true },
    "C:/Users/brown/Git/dev-env":             { "hasTrustDialogAccepted": false },
    "C:\Users\brown\Git\career-playbook": { "hasTrustDialogAccepted": true },
    "C:/Users/brown/Git/career-playbook":     { "hasTrustDialogAccepted": false }
  }
}

Expected: The trust lookup key should be normalized to a canonical form (e.g., always
backslash, or always path.resolve()) before reading or writing, so a single approval covers
both path representations.

---

Impact on scheduled routines

The combination means scheduled routines (nightly / weekly) fail to execute roughly every
few days:

  • Bug 2 can cause re-prompts intermittently after any session that writes a forward-slash key.
  • Bug 1 wipes the entire trust store under load, requiring manual interactive re-approval for

every workspace before routines work again.

bypassPermissions mode correctly skips tool-call permission prompts but does not bypass
the workspace trust gate — the gate runs before any session starts and cannot be configured
around.

---

Environment

  • OS: Windows 11 (10.0.26200)
  • Claude Code Desktop: 1.8555.2.0 (WindowsApps install)
  • Trust file: C:\Users\<user>\.claude.json (.projects[path].hasTrustDialogAccepted)
  • Log file: %APPDATA%\Claude\logs\main1.log

Workaround (partial)

Manually set hasTrustDialogAccepted: true for both path forms in .claude.json. Does not
fix the corruption race — the file can be wiped again by the next burst of concurrent writes.

View original on GitHub ↗

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