{"record":{"id":"c89d1330786c6bc7","repo":"QuantumNous/new-api","slug":"failed-to-initialize-oauth","errorCode":null,"errorMessage":"Failed to initialize OAuth","messagePattern":"Failed to initialize OAuth","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"web/src/features/auth/api.ts","lineNumber":157,"sourceCode":"\n// Get OAuth state for CSRF protection\nexport async function createOAuthFlow(\n  provider: string,\n  intent: 'login' | 'bind'\n): Promise<string> {\n  const aff = intent === 'login' ? getAffiliateCode() : ''\n  const res = await api.post(\n    '/api/oauth/state',\n    { provider, intent, aff: aff || undefined },\n    { skipAuthRefresh: intent === 'login' }\n  )\n  if (res.data?.success) {\n    if (typeof res.data.data === 'string') return res.data.data\n    if (typeof res.data.data?.flow_token === 'string') {\n      return res.data.data.flow_token\n    }\n  }\n  throw new Error(res.data?.message || 'Failed to initialize OAuth')\n}\n\n// WeChat login by authorization code\nexport async function wechatLoginByCode(code: string): Promise<ApiResponse> {\n  const res = await api.get('/api/oauth/wechat', { params: { code } })\n  return res.data\n}\n\nexport async function telegramLogin(\n  authorization: TelegramAuthorization\n): Promise<ApiResponse> {\n  const res = await api.get('/api/oauth/telegram/login', {\n    params: authorization,\n    disableDuplicate: true,\n    skipAuthRefresh: true,\n    skipBusinessError: true,\n    skipErrorHandler: true,\n  })","sourceCodeStart":139,"sourceCodeEnd":175,"githubUrl":"https://github.com/QuantumNous/new-api/blob/e2c7aa7b102c2075eae2377df3508658d45e88dc/web/src/features/auth/api.ts#L139-L175","documentation":"Thrown by getOauthState() after POST /api/oauth/state returns a body with success falsy (or a shape without a usable state/flow_token string). The backend OAuth state endpoint refused to initialize the flow, so the frontend cannot build the provider redirect URL. This is a server-side rejection surfaced to the caller, not a network exception (network failures would reject before reaching the throw).","triggerScenarios":"Calling the OAuth login/bind flow with a provider that is disabled or misconfigured server-side (missing client_id/secret in admin settings); POST /api/oauth/state returning {success:false, message:'...'}; backend returning success:true but data being neither a string nor an object with flow_token.","commonSituations":"Admin has not configured the GitHub/OIDC/Discord client credentials; the provider name sent does not match a registered provider; session/aff parameters rejected; backend upgraded and changed the state response shape so res.data.data is an unexpected type.","solutions":["Inspect the network response of POST /api/oauth/state — the server's message field usually names the exact cause (e.g. 'provider is not configured').","Verify the OAuth provider is enabled and has valid client_id/client_secret in the admin OAuth settings.","Confirm the provider string passed from the frontend matches a provider key the backend supports.","If the backend returns an unexpected data shape, update this function to read the new field (it currently accepts only string or data.flow_token)."],"exampleFix":"// before\nif (res.data?.success) {\n  if (typeof res.data.data === 'string') return res.data.data\n  if (typeof res.data.data?.flow_token === 'string') {\n    return res.data.data.flow_token\n  }\n}\nthrow new Error(res.data?.message || 'Failed to initialize OAuth')\n\n// after — surface the server message and unexpected shapes distinctly\nif (res.data?.success) {\n  if (typeof res.data.data === 'string') return res.data.data\n  if (typeof res.data.data?.flow_token === 'string') {\n    return res.data.data.flow_token\n  }\n  throw new Error('Unexpected OAuth state response shape')\n}\nthrow new Error(res.data?.message || 'Failed to initialize OAuth')","handlingStrategy":"try-catch","validationCode":"const OAUTH_PROVIDERS = new Set(['github', 'discord', 'oidc', 'linuxdo', 'wechat', 'telegram'])\nif (!OAUTH_PROVIDERS.has(provider)) {\n  throw new Error(`Unknown OAuth provider: ${provider}`)\n}","typeGuard":"const isOauthProvider = (p: unknown): p is string =>\n  typeof p === 'string' && p.length > 0","tryCatchPattern":"try {\n  const state = await getOauthState(provider, intent)\n  window.location.assign(buildAuthorizeUrl(provider, state))\n} catch (e) {\n  toast.error(getErrorMessage(e) || 'Failed to initialize OAuth')\n  setBusy(false)\n}","preventionTips":["Configure provider client_id/secret in admin settings before exposing the button","Verify provider names against the backend route list when adding a new provider","Log res.data on failure once during development to catch response-shape drift early"],"tags":["oauth","authentication","api-response","frontend"],"backgroundTag":null,"analyzedSha":"e2c7aa7b102c2075eae2377df3508658d45e88dc","analyzedAt":"2026-08-15T10:35:18.111Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}