Multiple CLI sessions race on ~/.claude/.credentials.json token refresh
Summary
When multiple Claude Code CLI sessions run concurrently, they share ~/.claude/.credentials.json for OAuth token storage with no file-level locking. When one session refreshes its access token (writing new access + refresh tokens to the file), other sessions holding the old tokens in memory get 401s. Their subsequent refresh attempts may fail if the server rotates refresh tokens, causing a cascading "logged out" state across sessions.
Reproduction
- Open 3-4 terminal tabs, each running
claudein different project directories - Wait for any session's access token to approach expiry (or trigger a refresh)
- One session refreshes successfully and writes new tokens to
.credentials.json - Other sessions get 401, attempt refresh with the now-stale refresh token
- Those sessions report "logged out" and prompt for
/login - Running
/loginin one session invalidates the tokens the first session just wrote - Cascade continues
Environment
- Claude Code 2.1.116
- macOS (Darwin 25.4.0, arm64)
- 4 concurrent CLI sessions + Desktop app (separate token store)
- Claude Max subscription
Expected Behavior
Multiple concurrent CLI sessions should be able to share credentials without racing. Options:
- File-level locking (flock/fcntl) around read-modify-write of
.credentials.json - Per-session token storage with a shared refresh coordinator
- Re-read the file before refreshing to check if another session already refreshed
- IPC-based token refresh coordination (only one session refreshes, others wait)
Additional Context
The problem is amplified when other tools (e.g., credential managers) also do read-modify-write operations on the same file for MCP OAuth tokens stored in the mcpOAuth key. The lack of file locking means any concurrent writer can roll back another's token update.
🤖 Generated with Claude Code
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗