Skip to content

Fix unauthorized sessions to persist without auto-retry#190

Open
jancurn wants to merge 2 commits intomainfrom
claude/fix-session-auth-check-HCcjy
Open

Fix unauthorized sessions to persist without auto-retry#190
jancurn wants to merge 2 commits intomainfrom
claude/fix-session-auth-check-HCcjy

Conversation

@jancurn
Copy link
Copy Markdown
Member

@jancurn jancurn commented Apr 18, 2026

Summary

This PR fixes how mcpc handles sessions that fail with authentication errors. Previously, sessions using static bearer tokens (via --header "Authorization: ...") would incorrectly flip between unauthorized and connecting status on every mcpc invocation after the auto-retry cooldown elapsed. Now they properly stay unauthorized since retrying the same rejected token cannot succeed without user intervention.

Additionally, authentication errors now include the path to the bridge log file to help users investigate failures.

Key Changes

  • Session retry logic: Modified consolidateSessions() to only auto-retry unauthorized sessions that have an OAuth profile. Sessions without a profile (static bearer tokens) cannot self-heal and are excluded from automatic retry, preventing the status flip issue
  • Error messages: Enhanced createServerAuthError() to accept and display a logPath parameter, pointing users to the bridge log file for debugging
  • Bridge manager: Updated classifyAndThrowSessionError() and ensureBridgeReady() to pass the bridge log file path when creating auth errors
  • Session connect: Updated connectSession() command to include the log path in auth error messages
  • Documentation: Added changelog entries explaining the fix for both bearer token sessions and the new log path guidance

Implementation Details

The core fix distinguishes between two types of unauthorized sessions:

  • OAuth-profile sessions: Can self-heal if tokens are refreshed by another session sharing the same profile, so they remain eligible for auto-retry
  • Bearer-token sessions: Cannot self-heal since the token is static, so they should not be retried automatically

This prevents the confusing behavior where a session would appear to be retrying indefinitely without user action, while still supporting the legitimate use case of token refresh across sessions.

https://claude.ai/code/session_011CjxmErafRX4ypgb2CQkea

claude added 2 commits April 18, 2026 09:42
Unauthorized sessions were being flipped back to 'connecting' by
consolidateSessions() on every `mcpc` invocation, even when the only
credentials were a static bearer token supplied via --header. These
retries cannot succeed because the token never changes, so the displayed
status kept toggling between 'connecting' and 'unauthorized' and the
real state was only surfaced once the user actually hit the session.

Scope the auto-retry to sessions with an OAuth profile, where another
session may have refreshed the shared tokens in the keychain.

Also include the bridge log path in the server auth error so the user
has a pointer for debugging, matching how the expired-session error
already surfaces the log path.

https://claude.ai/code/session_011CjxmErafRX4ypgb2CQkea
Covers the two guarantees added in the previous commit:

- A bearer-only session that fails the initial connect returns exit
  code 4 and an auth error whose message includes the bridge log path
  (`check logs at .../bridge-<session>.log`).
- The failed session stays `unauthorized` across `mcpc` invocations,
  even after `lastConnectionAttemptAt` is aged past the 10s auto-retry
  cooldown. Before the fix, consolidateSessions() would flip the status
  back to `connecting` whenever the cooldown window had elapsed.

The cooldown assertion fakes the post-failure bridge state (old
`lastConnectionAttemptAt`, pid cleared) by editing sessions.json
directly — otherwise we'd need to wait 10+ seconds for the bridge to
exit on its own, which would slow the suite down.

Verified both ways: test passes with the fix, reverting only
src/lib/sessions.ts causes assertion 3 to fail with exactly the
regression message (`expected status to stay 'unauthorized' after
cooldown, got: 'connecting'`).

https://claude.ai/code/session_011CjxmErafRX4ypgb2CQkea
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants