fix(server): respawn Claude after an expired login - #9468
Open
robertnisipeanu wants to merge 1 commit into
Open
Conversation
Claude Code loads its OAuth credentials once per process. After they expire, the long-lived CLI behind a thread keeps answering "Not logged in" even once the user has run /login elsewhere, until the idle reaper kills it. When the CLI reports an assistant message with error "authentication_failed", the adapter fails the turn with the CLI's message and stops the session, so the next turn spawns a fresh CLI with the current credentials. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Contributor
ApprovabilityVerdict: Not approved Macroscope's review found this PR not approvable — The production Claude adapter now changes authentication-failure handling and terminates sessions so later turns can respawn with refreshed credentials. Because this is an authentication-related runtime lifecycle change, it requires human review despite its focused scope and targeted tests. You can add or adjust custom eligibility rules. Learn more. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #9607
Problem
Claude Code loads its OAuth credentials once per process. T3 Code keeps one long-lived CLI per thread, so after the credentials expire that thread keeps answering "Not logged in · Please run /login" even after the user logs in again from a terminal. New threads work because they spawn a fresh CLI. The stuck thread only recovers once the idle reaper kills its process, up to 30 minutes later, or after a manual Stop.
Fix
When the CLI reports an assistant message with
error: "authentication_failed", the Claude adapter:The stop runs on the stream fiber itself, so
stopSessionInternalskips interrupting that fiber and lets the stream end through its ownstoppedcheck. The first auth-failure message in a turn wins, so a repeated failure does not duplicate the runtime error or replace the CLI's message with the fallback.Testing
vp test run apps/server/src/provider/Layers/ClaudeAdapter.test.ts(81 passed, two new tests: auth failure with text, and repeated auth failure without text)Built with Claude Fable 5.1 in Claude Code.
🤖 Generated with Claude Code
Note
Medium Risk
Changes Claude session lifecycle and turn completion on auth errors; incorrect handling could drop sessions prematurely or leave stale CLI processes, but behavior is scoped to
authentication_failedand covered by new tests.Overview
Fixes threads stuck on “Not logged in” after the user re-authenticates by treating Claude CLI
authentication_failedassistant messages as a hard session failure and tearing down the long-lived process so the next message spawns a fresh CLI with current credentials.The Claude adapter records the first auth failure per turn in
authenticationError, fails the turn with the CLI’s text (or aruntime.errorplus fallback when there is no text), skips duplicating that message as a generic runtime error, and callsstopSessionInternalafterturn.completed.stopSessionInternalno longer interrupts the stream fiber when stop is invoked from that same fiber, avoiding a self-deadlock while the session exits.Tests cover auth failure with CLI text (failed turn,
session.exited, no session, one close) and repeated empty auth messages (single runtime error, first message wins).Reviewed by Cursor Bugbot for commit 5222edf. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Fix
ClaudeAdapterto handle expired-login failures and stop the sessionClaudeSessionContextthat stores the first authentication-failed message text from the Claude CLI per turn/sessionauthentication_failed, the handler in ClaudeAdapter.ts extracts and stores its text once; textless failures emit a singleruntime.errorwith a fallback message and repeated failures are suppressedruntime.errorstopSessionInternalnow skips interrupting the stream fiber when shutdown is invoked from that same fiber, while still interrupting a distinct live stream fiberMacroscope summarized 5222edf.