coleam00/Archon · error
Failed to start subscription login
Error message
Failed to start subscription login
What it means
Generic failure branch of the provider OAuth subscription-login start route. Any error starting the OAuth flow that is NOT OAuthCallbackPortBusyError is logged at error level (auth.provider_oauth_start_failed, with err and provider attached) and returned as HTTP 500 with this opaque message, so provider-specific detail stays in server logs rather than the response.
Source
Thrown at packages/server/src/routes/api.ts:2065
);
}
try {
const start = await startOAuth(web.userId, provider);
return c.json(start);
} catch (err) {
// A leaked callback port from a previous attempt is an expected,
// retryable condition — log it at warn under its own event (an
// error-level `…_failed` would pollute error dashboards on multi-user
// installs) and surface the actionable message as a 503 instead of an
// opaque 500 (#1963).
if (err instanceof OAuthCallbackPortBusyError) {
getLog().warn({ userId: web.userId, provider }, 'auth.provider_oauth_start_port_busy');
return apiError(c, 503, err.message);
}
getLog().error(
{ err: err as Error, userId: web.userId, provider },
'auth.provider_oauth_start_failed'
);
return apiError(c, 500, 'Failed to start subscription login');
}
});
registerOpenApiRoute(providerOAuthPollRoute, async c => {
const web = await requireWebUser(c, 'Web authentication required to connect a subscription');
if ('error' in web) return web.error;
if (!isPerUserProviderKeysEnabled()) {
return apiError(c, 404, 'Per-user provider keys are not enabled on this install');
}
// The `:provider` path segment only keeps the OAuth routes under one prefix
// (so they're exempt from the Better Auth catch-all); poll itself keys off
// sessionId + userId.
const { sessionId, code } = getValidatedBody(c, providerOAuthPollBodySchema);
// pollOAuth is bound to the session's userId, so a stranger's sessionId resolves
// to an error status rather than another user's login.
const result = pollOAuth(sessionId, web.userId, code);
return c.json(result);View on GitHub (pinned to 0773b97458)
Solutions
- Check server logs for the auth.provider_oauth_start_failed entry — the err object carries the root cause (message/stack).
- Verify the provider is properly set up (its CLI authenticated or config file present) before retrying the login.
- Re-authenticate or refresh the provider credentials for that userId.
- Retry once; if persistent, run the provider login manually outside the API to surface the real error, then report it if it is engine-side.
Example fix
// diagnose from the response alone? Instead read the server log:
// getLog().error({ err, userId, provider }, 'auth.provider_oauth_start_failed')
$ grep provider_oauth_start_failed server.log | jq '.err.message' Defensive patterns
Strategy: try-catch
Validate before calling
// before calling the API, confirm the provider is set up
import { existsSync } from 'node:fs';
if (!existsSync(providerConfigPath(provider))) {
throw new Error(`Provider ${provider} is not configured; run its native login first`);
} Type guard
function isOAuthStartFailed(res: { status: number; error?: string }): res is { status: 500; error: 'Failed to start subscription login' } {
return res.status === 500 && res.error === 'Failed to start subscription login';
} Try / catch
try {
await startProviderOAuth(provider);
} catch (err) {
// response is intentionally opaque; read server log event for cause
const cause = await readServerLogEvent('auth.provider_oauth_start_failed');
throw new Error(`OAuth start failed: ${cause ?? err.message}`);
} Prevention
- Authenticate the provider via its native CLI/config before using the subscription-login route.
- Check the auth.provider_oauth_start_failed log entry for the err detail instead of relying on the generic 500 body.
- Re-run the provider login after any credential rotation or expiry.
- Report persistent failures with the log entry; the response alone cannot identify the cause.
When it happens
Trigger: Any exception in the OAuth-start path besides port-busy: provider SDK failing to build the auth URL, credential/subscription not found or invalid, callback-server construction throwing for a non-port reason, or an unexpected internal error.
Common situations: Provider CLI/SDK not installed or its config missing for the requested provider; expired or revoked provider credentials; a bug/regression in the OAuth-start code path; environment misconfiguration on a fresh self-hosted install.
Related errors
- Provider '${provider}' does not support subscription login.
- Vendor '${vendor}' (Pi backend) has no env-based OAuth deliv
- OAuth state mismatch.
- Missing authorization code.
- Provider '${providerId}' does not support subscription login
AI-assisted analysis of coleam00/Archon@0773b97458 (2026-09-01).
Data as JSON: /api/errors/986f68b8204173fa.
Report an issue: GitHub.