CherryHQ/cherry-studio · error · Error
OAuth authentication failed: ${oauthError instanceof Error ?
Error message
OAuth authentication failed: ${oauthError instanceof Error ? oauthError.message : String(oauthError)} What it means
Thrown when the OAuth authentication flow fails during `transport.finishAuth(authCode)` or the subsequent reconnection attempt (`client.connect(newTransport)`). The original error is logged via getServerLogger before being wrapped. This is a user-facing auth failure, not a transport-level protocol mismatch (those are handled by isTransportFallbackError separately).
Source
Thrown at src/main/ai/mcp/McpRuntimeService.ts:768
try {
// Wait for the authorization code
const authCode = await callbackServer.waitForAuthCode()
getServerLogger(server).debug(`Received auth code`)
// Complete the OAuth flow
await transport.finishAuth(authCode)
getServerLogger(server).debug(`OAuth flow completed`)
const newTransport = await initTransport(typeOverride)
// Try to connect again
await client.connect(newTransport)
getServerLogger(server).debug(`Successfully authenticated`)
} catch (oauthError) {
getServerLogger(server).error(`OAuth authentication failed`, oauthError as Error)
throw new Error(
`OAuth authentication failed: ${oauthError instanceof Error ? oauthError.message : String(oauthError)}`
)
} finally {
// Clear the timeout and close the callback server
clearTimeout(timeoutId)
void callbackServer.close()
}
}
try {
// Bound the MCP `initialize` request so a non-responsive server fails fast via the
// SDK's own abort path instead of hanging. Use a 180s floor (activation runs once,
// generous headroom is cheap) while still honoring larger `server.timeout` values
// that the user explicitly configured. transport.start() latency remains bounded
// by the underlying fetch / child_process, matching v1.8.4 behavior.
const connectOptions: RequestOptions = {
timeout: Math.max((server.timeout ?? 0) * 1000, MCP_CONNECT_TIMEOUT_FLOOR_MS)
}View on GitHub (pinned to 726446b54c)
Solutions
- Retry the OAuth flow from scratch — the callback server and timeout are cleaned up automatically
- Check the detailed server logs for the original oauthError message (logged before this throw)
- Verify the OAuth provider's metadata endpoint is accessible and the redirect URI is correctly registered
- If PKCE mismatch, clear the OAuth storage for this server and retry (storage.clear())
- Ensure the system clock is accurate — token validation is time-sensitive
Defensive patterns
Strategy: retry
Try / catch
const MAX_OAUTH_RETRIES = 2
for (let attempt = 0; attempt <= MAX_OAUTH_RETRIES; attempt++) {
try {
await runtime.getOrCreateClient(server)
break
} catch (e) {
if (e instanceof Error && e.message.startsWith('OAuth authentication failed') && attempt < MAX_OAUTH_RETRIES) {
// Clear stale OAuth state and retry the full flow
await oauthStorage.clear()
continue
}
throw e
}
} Prevention
- Ensure system clock is synchronized — OAuth tokens are time-sensitive
- Clear OAuth storage before retrying if the flow was interrupted
- Verify the OAuth provider's redirect URI matches what's registered on the server side
- Don't let auth codes sit too long before completing the callback
When it happens
Trigger: The OAuth callback delivers an auth code, but `finishAuth` rejects it (expired, already used, or PKCE mismatch), or the reconnection with the new transport fails due to network errors, invalid tokens, or server-side OAuth endpoint issues.
Common situations: Auth code expired before the user completed the consent flow; PKCE code_verifier doesn't match (storage issue); the OAuth server's token endpoint is down; redirect URI mismatch; the OAuth provider changed its API; network firewall blocks the token exchange.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- No code verifier saved for session
- Failed to open Socket Mode connection: HTTP ${response.statu
- Failed to read OAuth storage: ${error instanceof Error ? err
- Failed to write OAuth storage: ${error instanceof Error ? er
- Failed to clear OAuth storage: ${error instanceof Error ? er
AI-assisted analysis of CherryHQ/cherry-studio@726446b54c (2026-08-12).
Data as JSON: /api/errors/43fd830545ceaee4.
Report an issue: GitHub.