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

  1. Check server logs for the auth.provider_oauth_start_failed entry — the err object carries the root cause (message/stack).
  2. Verify the provider is properly set up (its CLI authenticated or config file present) before retrying the login.
  3. Re-authenticate or refresh the provider credentials for that userId.
  4. 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

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


AI-assisted analysis of coleam00/Archon@0773b97458 (2026-09-01). Data as JSON: /api/errors/986f68b8204173fa. Report an issue: GitHub.