claude-code - 💡(How to fix) Fix Multiple CLI sessions race on ~/.claude/.credentials.json token refresh [1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#56339Fetched 2026-05-06 06:30:48
View on GitHub
Comments
1
Participants
2
Timeline
5
Reactions
0
Timeline (top)
labeled ×4commented ×1

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.

Root Cause

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.

RAW_BUFFERClick to expand / collapse

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

  1. Open 3-4 terminal tabs, each running claude in different project directories
  2. Wait for any session's access token to approach expiry (or trigger a refresh)
  3. One session refreshes successfully and writes new tokens to .credentials.json
  4. Other sessions get 401, attempt refresh with the now-stale refresh token
  5. Those sessions report "logged out" and prompt for /login
  6. Running /login in one session invalidates the tokens the first session just wrote
  7. 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

extent analysis

TL;DR

Implement file-level locking or a token refresh coordination mechanism to prevent concurrent CLI sessions from overwriting each other's OAuth tokens.

Guidance

  • Consider using file-level locking (e.g., flock or fcntl) around read-modify-write operations on ~/.claude/.credentials.json to prevent concurrent modifications.
  • Alternatively, implement a per-session token storage with a shared refresh coordinator to avoid racing conditions.
  • Before refreshing a token, re-read the file to check if another session has already updated the tokens, and adjust the refresh attempt accordingly.
  • Evaluate the feasibility of using IPC-based token refresh coordination, where only one session refreshes the token and others wait for the updated token.

Example

import fcntl

with open('~/.claude/.credentials.json', 'r+') as file:
    fcntl.flock(file, fcntl.LOCK_EX)  # acquire exclusive lock
    # read, modify, and write the file
    fcntl.flock(file, fcntl.LOCK_UN)  # release the lock

Notes

The chosen solution should consider the trade-offs between complexity, performance, and security. Additionally, the implementation should account for potential edge cases, such as multiple sessions attempting to refresh the token simultaneously.

Recommendation

Apply a workaround using file-level locking, as it is a relatively simple and effective solution to prevent concurrent modifications to the ~/.claude/.credentials.json file. This approach can help mitigate the cascading "logged out" state across sessions until a more comprehensive solution is implemented.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

claude-code - 💡(How to fix) Fix Multiple CLI sessions race on ~/.claude/.credentials.json token refresh [1 comments, 2 participants]