{"record":{"id":"97c07f6ad27e227c","repo":"coleam00/Archon","slug":"subscription-login-failed-to-start","errorCode":null,"errorMessage":"Subscription login failed to start.","messagePattern":"Subscription login failed to start\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/core/src/credentials/oauth-bridge.ts","lineNumber":388,"sourceCode":"    });\n\n  // Wait for the first callback so the URL / user-code is available to return.\n  await Promise.race([session.firstSignal.promise, sleep(START_FIRST_SIGNAL_MS)]);\n\n  // An early login() failure → throw (route returns 500, CLI prints the message)\n  // rather than returning a misleading { mode:'manual', url:undefined } (I1).\n  if (session.status === 'error') {\n    sessions.delete(sessionId);\n    if (session.portBusy) {\n      // Retryable: the cancel above releases the port as soon as the previous\n      // login unwinds (microtasks for pi flows), so \"retry shortly\" is honest\n      // advice — and a restart always clears it (#1963).\n      throw new OAuthCallbackPortBusyError(\n        `A previous '${provider}' login attempt is still holding the OAuth callback port. ` +\n          'Wait a few seconds and retry; if it persists, restart the Archon server.'\n      );\n    }\n    throw new Error(session.detail ?? 'Subscription login failed to start.');\n  }\n\n  // Superseded (or cancelled) while still waiting for the first signal — the\n  // session is already gone from the map, so a 200 here would hand back a\n  // url-less session the first poll immediately reports as \"not found\".\n  // Throw the honest answer instead (S4).\n  if (!sessions.has(sessionId)) {\n    throw new Error('Login attempt was superseded by a newer one. Retry to start a fresh login.');\n  }\n\n  return {\n    sessionId,\n    mode: externalMode(session),\n    url: session.url,\n    userCode: session.userCode,\n    verificationUri: session.verificationUri,\n    expiresIn: Math.round(SESSION_TTL_MS / 1000),\n  };","sourceCodeStart":370,"sourceCodeEnd":406,"githubUrl":"https://github.com/coleam00/Archon/blob/0773b9745896ef0612e709c80845a0f7db315b19/packages/core/src/credentials/oauth-bridge.ts#L370-L406","documentation":"Generic failure in startOAuth (oauth-bridge.ts:388): the login chain rejected before producing a URL/user-code and the failure was not classified as port-busy. The bridge throws session.detail (the sanitized, truncated underlying error) or this fallback string when detail is missing. It signals the subscription login could not even begin.","triggerScenarios":"Calling startOAuth when the underlying pi login() (or the openai manual flow) rejects before the first auth callback — e.g. network failure reaching the authorization endpoint, provider misconfiguration, or any early error without session.detail set.","commonSituations":"Corporate proxy or DNS blocking the provider's auth endpoint; expired/invalid provider configuration; pi-ai login throwing on startup; offline environment; the rare case where the underlying error message was empty or sanitized to nothing.","solutions":["Inspect the thrown message — if it equals this fallback, check server logs (oauth_bridge.login_failed warn) for the sanitized underlying error.","Verify network/proxy access to the provider's OAuth endpoints.","Retry the login; if consistent, check provider configuration and package versions.","Restart the Archon server to clear any stuck in-flight login state."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Pre-check basic reachability of the provider auth endpoint before starting a login\nconst ok = await fetch('https://anthropic.com', { method: 'HEAD' }).then(r => r.ok).catch(() => false);\nif (!ok) throw new Error('Network unreachable; fix connectivity before login.');","typeGuard":null,"tryCatchPattern":"try {\n  await startOAuth(userId, providerId);\n} catch (e) {\n  const msg = e instanceof Error ? e.message : '';\n  if (msg === 'Subscription login failed to start.' || !msg) {\n    // Detail was missing: consult server logs (oauth_bridge.login_failed)\n    getLog().error({ userId, providerId }, 'subscription_login_failed_opaque');\n  }\n  throw e;\n}","preventionTips":["Ensure server logs are collected — the underlying sanitized error lands in the oauth_bridge.login_failed warn entry.","Verify outbound access to provider OAuth endpoints before prompting users to log in.","Keep the bridge and provider packages current; many startup failures are version-related."],"tags":["oauth","network","login-startup"],"backgroundTag":"oauth-login-failed","analyzedSha":"0773b9745896ef0612e709c80845a0f7db315b19","analyzedAt":"2026-09-01T02:28:07.064Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}