{"record":{"id":"7ba1286823fd8be7","repo":"nexu-io/open-design","slug":"xai-oauth-state-not-found-or-expired","errorCode":null,"errorMessage":"xAI OAuth state not found or expired","messagePattern":"xAI OAuth state not found or expired","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"apps/daemon/src/integrations/xai-oauth.ts","lineNumber":131,"sourceCode":"export interface CompleteXAIAuthInput {\n  pending: PendingAuthCache;\n  state: string;\n  code: string;\n  fetchImpl?: typeof fetch;\n}\n\n/**\n * Post-callback half of the OAuth dance. Looks up `state` in `pending`,\n * validates it (one-shot, TTL-checked by `PendingAuthCache`), and\n * exchanges `code` for tokens. Throws if `state` is unknown, expired,\n * already consumed, or was issued for a different provider.\n */\nexport async function completeXAIAuth(\n  input: CompleteXAIAuthInput,\n): Promise<OAuthTokenResponse> {\n  const consumed = input.pending.consume(input.state);\n  if (!consumed) {\n    throw new Error('xAI OAuth state not found or expired');\n  }\n  if (consumed.serverId !== XAI_PROVIDER_ID) {\n    throw new Error(\n      `xAI OAuth state mismatch: expected serverId=${XAI_PROVIDER_ID}, got ${consumed.serverId}`,\n    );\n  }\n  return exchangeCodeForToken(\n    {\n      tokenEndpoint: consumed.tokenEndpoint,\n      clientId: consumed.clientId,\n      redirectUri: consumed.redirectUri,\n      code: input.code,\n      codeVerifier: consumed.codeVerifier,\n    },\n    input.fetchImpl ?? fetch,\n  );\n}\n","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/apps/daemon/src/integrations/xai-oauth.ts#L113-L149","documentation":"Raised by completeXAIAuth() when input.pending.consume(input.state) returns null. PendingAuthCache.consume is a one-shot, TTL-checked lookup: it returns null if the state is unknown, expired, already consumed, or the cache was never seeded by the matching startXAIAuth call. This is the post-callback half of the PKCE OAuth flow.","triggerScenarios":"The OAuth callback arrives with a state value that was never stored (startXAIAuth not called), was stored but TTL-expired, was already consumed (double callback / refresh), or belongs to a different daemon process whose in-memory cache did not hold it.","commonSituations":"User opened the callback URL twice (browser pre-fetch + real navigation); too much time between authorize and callback (TTL); daemon restarted between starting auth and the callback (in-memory cache lost); callback received by a different worker/process; state parameter corrupted in transit.","solutions":["Restart the OAuth flow from startXAIAuth to mint a fresh state, then complete promptly within the TTL.","Ensure the callback hits the same daemon process that started the flow (sticky routing / single worker).","Avoid double-processing the callback URL (dedupe on state)."],"exampleFix":"// before\nconst consumed = input.pending.consume(input.state);\nif (!consumed) throw new Error('xAI OAuth state not found or expired');\n\n// after (return a structured result so the route can render a friendly page)\nconst consumed = input.pending.consume(input.state);\nif (!consumed) {\n  return { ok: false, reason: 'state_expired_or_unknown' };\n}","handlingStrategy":"try-catch","validationCode":"function isPlausibleOAuthState(state: unknown): state is string {\n  return typeof state === 'string' && state.length > 16;\n}\n\n// usage: reject obviously bad callbacks before consuming\nif (!isPlausibleOAuthState(input.state)) {\n  return { ok: false, reason: 'invalid_state' };\n}","typeGuard":"function isOAuthStateNotFound(err: unknown): boolean {\n  return err instanceof Error && err.message === 'xAI OAuth state not found or expired';\n}","tryCatchPattern":"try {\n  return await completeXAIAuth(input);\n} catch (err) {\n  if (err instanceof Error && err.message === 'xAI OAuth state not found or expired') {\n    return { ok: false, reason: 'state_expired_or_unknown' };\n  }\n  throw err;\n}","preventionTips":["Route callbacks to the same daemon process that started the flow (sticky routing).","Complete the callback promptly within the PendingAuthCache TTL.","Dedupe callbacks on state to avoid double-consume (one-shot cache)."],"tags":["oauth","integration","auth","xai"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}