[BUG]OAuth session invalidated by concurrent headless claude --print calls — desktop app logs out despite never closing
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
The Claude Code desktop app repeatedly prompts for re-authentication throughout the day, even though the app is never closed or quit. This happens alongside sporadic "Failed to authenticate: OAuth session expired and could not be refreshed" errors from headless claude --print --dangerously-skip-permissions calls running as scheduled macOS LaunchAgents (11 separate agents firing at various times throughout the trading day, each running independent claude --print invocations against the same account).
Evidence of correlation:
macOS Keychain entry Claude Code-credentials (service), account kimberlyt, shows mdat (last modified) timestamp of 2026-10-01 11:00:04 UTC — this is exactly 7:00:04 AM EDT, the precise second-level timestamp when one of the scheduled claude --print LaunchAgents fires daily.
Only one credential entry exists in the keychain (ruled out duplicate/conflicting entries).
System clock is synced to within 15ms of time.apple.com (ruled out clock drift as a cause of premature expiry judgment).
The desktop app then separately prompts for login even though it was never closed, on days that otherwise correlate with scheduled script activity.
Hypothesis: the desktop app and headless claude --print invocations share the same stored OAuth session/refresh token. When a background script triggers a token refresh/rotation on that shared credential, the desktop app's own in-memory copy of the prior token becomes stale and gets rejected, forcing a re-login — despite the app itself never having been closed or idle-timed-out.
Impact: scheduled automation silently fails until manually re-authenticated via /login, and the interactive desktop app repeatedly interrupts the user with login prompts during active use, despite the app staying open continuously.
Expected behavior: either (a) the desktop app and headless CLI invocations should use independent sessions, or (b) a token refresh triggered by one should propagate cleanly to the other rather than invalidating it.
What Should Happen?
Expected behavior: either (a) the desktop app and headless CLI invocations should use independent sessions, or (b) a token refresh triggered by one should propagate cleanly to the other rather than invalidating it.
Error Messages/Logs
Steps to Reproduce
Steps to Reproduce:
Set up multiple scheduled/automated invocations of claude --print --dangerously-skip-permissions (e.g., via macOS LaunchAgents, cron, or any scheduler) running at various times throughout the day under the same logged-in account.
Keep the Claude Code desktop app open and running continuously in the background without closing it.
Over the course of normal use (observed across multiple separate days — Aug 31, Sep 29, Oct 1), the desktop app will unexpectedly prompt for re-login, with no action taken by the user (no quit, no idle timeout triggered manually).
Separately, some of the scheduled headless invocations from step 1 will intermittently fail with "Failed to authenticate: OAuth session expired and could not be refreshed".
This is not reliably reproducible on a fixed schedule — it appears tied to when a background claude --print call happens to trigger a token refresh on the shared OAuth credential. One concrete data point: on 2026-10-01, the macOS Keychain entry for Claude Code-credentials showed its mdat (last-modified) timestamp at 11:00:04 UTC, matching to the second a scheduled claude --print LaunchAgent that fires at 7:00:04 AM EDT daily — suggesting the credential refresh from that background process is what destabilizes the shared session.
Workaround attempted: none available from the user side other than re-running /login in a terminal session or re-authenticating the desktop app when prompted; no setting was found to isolate sessions between headless and interactive usage.
Claude Model
Sonnet (default)
Is this a regression?
Yes, this worked in a previous version
Last Working Version
Last working version: 2.1.260 (same version still in use) — this is not a version regression. The same build was running cleanly for roughly 4 weeks (Aug 31 – Sep 29) before the symptom recurred, with no update in between. This points to the issue being intermittent/load-dependent (likely tied to how often concurrent background claude --print calls happen to collide with a token refresh) rather than something a specific release broke.
Claude Code Version
2.1.260 (Claude Code)
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
Version: 2.1.260 (Claude Code) — confirmed via claude --version. Not a regression: this exact build has been installed continuously since 2026-09-03, including a ~4-week stretch (Aug 31 – Sep 29) where the issue did not occur at all.
Description:
The Claude Code desktop app repeatedly prompts for re-authentication throughout the day, even though the app is never closed or quit. This happens alongside sporadic "Failed to authenticate: OAuth session expired and could not be refreshed" errors from headless claude --print --dangerously-skip-permissions calls running as scheduled macOS LaunchAgents (11 separate agents firing at various times throughout the trading day, each running independent claude --print invocations under the same account).
Evidence of correlation:
macOS Keychain entry Claude Code-credentials (service), account kimberlyt, shows mdat (last modified) timestamp of 2026-10-01 11:00:04 UTC — exactly 7:00:04 AM EDT, the precise second-level timestamp a scheduled claude --print LaunchAgent fires daily.
Only one credential entry exists in the keychain (ruled out duplicate/conflicting entries).
System clock synced to within 15ms of time.apple.com (ruled out clock drift as a cause of premature expiry judgment).
The desktop app separately prompts for login on the same days scheduled script auth failures occur, despite never being closed.
Hypothesis: the desktop app and headless claude --print invocations share the same stored OAuth session/refresh token. When a background script triggers a token refresh/rotation on that shared credential, the desktop app's own in-memory copy of the prior token becomes stale and gets rejected, forcing a re-login — despite the app itself never having been closed or idle-timed-out.
Frequency / history: intermittent, not tied to a specific release. Observed occurrences: a multi-day stretch in late July, one day on Aug 31, then a clean ~4-week gap with zero issues (confirmed via local script logs), then recurring again Sep 29 – Oct 1. This pattern suggests the trigger is load/timing-dependent (how often a background process happens to collide with a token refresh) rather than a code regression from a specific version.
Steps to Reproduce:
Set up multiple scheduled/automated invocations of claude --print --dangerously-skip-permissions (e.g., via macOS LaunchAgents, cron, or any scheduler) running at various times throughout the day under the same logged-in account.
Keep the Claude Code desktop app open continuously without closing it.
Over normal use spanning multiple days, the desktop app will unexpectedly prompt for re-login with no user action taken.
Separately, some scheduled headless invocations from step 1 will intermittently fail with "Failed to authenticate: OAuth session expired and could not be refreshed".
Not reliably reproducible on a fixed schedule — it's tied to when a background call happens to trigger a credential refresh.
Impact: scheduled automation silently fails until manually re-authenticated via /login; the interactive desktop app repeatedly interrupts active use with login prompts despite staying open continuously.
Expected behavior: either (a) the desktop app and headless CLI invocations use independent sessions, or (b) a token refresh triggered by one propagates cleanly to the other rather than invalidating it.
Workaround attempted: none available from the user side beyond re-running /login when prompted; no setting found to isolate sessions between headless and interactive usage.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗