{"record":{"id":"e76a6eaa050d4835","repo":"coleam00/Archon","slug":"provider-providerid-does-not-support-subscrip","errorCode":null,"errorMessage":"Provider '${providerId}' does not support subscription login.","messagePattern":"Provider '(.+?)' does not support subscription login\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/core/src/credentials/oauth-bridge.ts","lineNumber":245,"sourceCode":"}\n\n/**\n * Begin a subscription login for a vendor (anthropic/openai/github-copilot;\n * legacy claude/codex/copilot ids accepted). Kicks off the held login —\n * Pi's `login()` for anthropic/github-copilot, the Archon-owned PKCE flow for\n * openai — and returns once the first signal has populated the URL (manual)\n * or user-code (device), or a short timeout elapses.\n */\nexport async function startOAuth(userId: string, providerId: string): Promise<StartOAuthResult> {\n  // Expired sessions may also hold a callback server — include them in the\n  // settle-wait below so the port is free before the new login binds it.\n  const supersededSettled: Promise<void>[] = sweepExpired();\n  const provider = normalizeCredentialVendor(providerId);\n  // SUBSCRIPTION_PROVIDERS is the single source of truth for \"connectable via\n  // subscription\". Gate here too so the bridge can't be driven past the\n  // route/CLI check.\n  if (!SUBSCRIPTION_PROVIDERS.has(provider)) {\n    throw new Error(`Provider '${providerId}' does not support subscription login.`);\n  }\n  // `openai` (ChatGPT/Codex) runs the Archon-OWNED PKCE flow (openai-oauth.ts)\n  // instead of Pi's: Pi drops the id_token the Codex CLI requires (#1924), and\n  // Pi's flow would also bind a local fixed-port callback server — the #1963\n  // wedge pattern this bridge just escaped. piProvider stays undefined for it.\n  const piProvider =\n    provider === OPENAI_SUBSCRIPTION_VENDOR ? undefined : piOAuthProviderFor(provider);\n  if (provider !== OPENAI_SUBSCRIPTION_VENDOR && !piProvider) {\n    throw new Error(`Provider '${providerId}' does not support subscription login.`);\n  }\n  // Hard-cancel prior in-flight logins that would collide with this one:\n  //   - same user (one login per user — the original I3 behavior), and\n  //   - same vendor when the flow binds a local fixed-port callback server\n  //     (anthropic: 53692). Two such logins can't coexist in one process, and\n  //     an abandoned one would otherwise EADDRINUSE every later start for ANY\n  //     user until restart (#1963). The newest interactive request wins; a\n  //     superseded session's user sees \"session not found\" on their next poll\n  //     and can simply restart — recoverable, so the heuristic is acceptable.","sourceCodeStart":227,"sourceCodeEnd":263,"githubUrl":"https://github.com/coleam00/Archon/blob/0773b9745896ef0612e709c80845a0f7db315b19/packages/core/src/credentials/oauth-bridge.ts#L227-L263","documentation":"Thrown by startOAuth in packages/core/src/credentials/oauth-bridge.ts:245 when the requested provider id is not in SUBSCRIPTION_PROVIDERS, the single source of truth for which vendors can be connected via subscription (OAuth) login. This is the deep gate inside the bridge, beyond the route/CLI check, so the bridge can never be driven past it. It means the provider must use an API-key credential instead.","triggerScenarios":"Calling startOAuth(userId, providerId) with a provider id that normalizes to a vendor outside SUBSCRIPTION_PROVIDERS (e.g. 'openai' API-key-only configs, unknown/misspelled ids like 'anthropicai', or an API-key provider such as a plain OpenAI key vendor).","commonSituations":"Typo in the provider id in a CLI command or HTTP route call; passing a raw display name or alias that normalizeCredentialVendor maps to a non-subscription vendor; calling the bridge directly in a test or script for a vendor that only supports API keys; version drift where a new vendor was added to routes but not to SUBSCRIPTION_PROVIDERS.","solutions":["Use one of the supported subscription provider ids: anthropic (or legacy claude), openai/codex, github-copilot (or copilot).","Check spelling/casing of the provider id before calling startOAuth.","If the provider only supports API keys, configure it via the API-key credential path instead of subscription login.","If you are adding a new vendor, add it to SUBSCRIPTION_PROVIDERS (and provide piOAuthProviderFor or an owned flow) before routing to startOAuth."],"exampleFix":"// before\nawait startOAuth(userId, 'claude-code');\n// after\nawait startOAuth(userId, 'anthropic');","handlingStrategy":"validation","validationCode":"import { SUBSCRIPTION_PROVIDERS, normalizeCredentialVendor } from '@archon/core/credentials';\nif (!SUBSCRIPTION_PROVIDERS.has(normalizeCredentialVendor(providerId))) {\n  throw new Error(`Provider '${providerId}' is not connectable via subscription login.`);\n}\nawait startOAuth(userId, providerId);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Maintain a UI/CLI picker that only offers providers in SUBSCRIPTION_PROVIDERS.","Normalize provider ids through normalizeCredentialVendor at every entry point.","Add a test asserting every route-advertised login provider exists in SUBSCRIPTION_PROVIDERS."],"tags":["oauth","provider-configuration","invalid-argument"],"backgroundTag":"unsupported-provider","analyzedSha":"0773b9745896ef0612e709c80845a0f7db315b19","analyzedAt":"2026-09-01T02:28:07.064Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}