[BUG] Linux Desktop: OAuth login callback dropped as "repeat delivery", making /login recovery impossible
App: Claude desktop app (Linux/Arch), version 2.110.0
claude-code: 2.1.271
OS: Linux 7.2.6-arch2-1, KDE/Wayland
Summary
When the app demands a re-login (Login expired · Please run /login), completing the OAuth flow in the system browser has no effect: the returning callback is discarded by claudeURLHandler as a duplicate. No new credential is minted, ~/.claude/.credentials.json is never rewritten, and the session asks for /login again — indefinitely.
This makes the documented recovery path for #93014 (session_stale_relogin latch) unusable.
Reproduction
Observed after a session_stale_relogin latch (see #93014). Three consecutive /login attempts, each one completing normally in the browser:
21:09:32 [Auth] Using system browser for: /login/app-google-auth
21:09:43 claudeURLHandler: ignoring repeat delivery of login callback
21:10:31 [Auth] Using system browser for: /login/app-google-auth
21:10:40 claudeURLHandler: ignoring repeat delivery of login callback
21:11:40 [Auth] Using system browser for: /login/app-google-auth
21:11:49 claudeURLHandler: ignoring repeat delivery of login callback
Three attempts, three callbacks, three drops. ~11 s between opening the browser and the dropped callback each time — consistent with the flow actually being completed, not abandoned.
Evidence that no credential was written
~/.claude/.credentials.json mtime stayed at 19:12:45 throughout, and was still unchanged at 23:01 — nearly two hours after the last attempt. The Secret Service store (KWallet) was last written the previous day, so nothing landed there either.
What did happen
The app re-authorized itself on each attempt, rewriting ~/.claude.json at 21:09:46, 21:10:56 and 21:11:59:
21:09:43 [oauth] clearing latched session_stale_relogin failures
21:09:44 [oauth-v2] performing fresh /authorize for orgId=<redacted>
21:09:45 [oauth-v2] credential widened to user:plugins for orgId=<redacted>
So the app-side credential recovered — Remote Control went back to connected at 21:15:25. But the CLI-facing credential was never re-minted, so every CLI refresh kept being served the cached, already-dead token:
21:15:25 [oauth] CLI requested token refresh after 401
21:15:25 [oauth-v2] using cached token for orgId=<redacted>
That is the loop: CLI hits 401 → asks for refresh → receives the same dead cached token → 401 → prompts /login → callback dropped → repeat.
Impact
A long-running CLI session cannot be recovered in place. The only workaround found was to kill the process and start a fresh one, which reads valid credentials from disk on startup. For users driving a machine remotely this is severe: the recovery action the UI explicitly instructs them to take does nothing, with no error shown.
Note
The only other occurrence of ignoring repeat delivery of login callback in ~6 days of logs is a single benign one at app startup. During a genuinely required re-login it fires every time.
Related: #93014 (the latch that triggered the re-login demand).
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗