decolua/9router · error

No authorization code received

Error message

No authorization code received

What it means

connect() requires the OAuth redirect to carry an authorization `code` query parameter. The callback arrived without one and without an `error`, so there is nothing to exchange for tokens and the flow aborts. This guards against completing a connect() with an empty/redirected callback that cannot yield tokens.

Source

Thrown at src/lib/oauth/services/xai.js:219

      await open(authUrl);

      spinner.start("Waiting for xAI authorization...");
      await new Promise((resolve, reject) => {
        const timeout = setTimeout(() => reject(new Error("Authentication timeout (5 minutes)")), 300000);
        const iv = setInterval(() => {
          if (callbackParams) {
            clearInterval(iv);
            clearTimeout(timeout);
            resolve();
          }
        }, 100);
      });
      close();

      if (callbackParams.error) {
        throw new Error(callbackParams.error_description || callbackParams.error);
      }
      if (!callbackParams.code) throw new Error("No authorization code received");
      if (callbackParams.state !== state) throw new Error("Invalid state parameter");

      spinner.start("Exchanging code for tokens...");
      const tokens = await this.exchangeXaiCode({
        tokenUrl,
        code: callbackParams.code,
        redirectUri,
        codeVerifier,
      });

      const email = decodeIdTokenEmail(tokens.id_token);
      spinner.succeed("xAI connected successfully!");
      return { tokens, email };
    } catch (error) {
      spinner.fail(`Failed: ${error.message}`);
      throw error;
    }
  }

View on GitHub (pinned to 90b52e06ff)

Solutions

  1. Re-run connect() and complete the full browser authorization so xAI redirects back with ?code=...
  2. Check that nothing else (another dev server, a previous run) is occupying the loopback port and answering the callback first
  3. Verify the redirect_uri used in the authorize URL matches what xAI redirects to (same host/port/path)
  4. Open the printed authUrl in a normal browser window without extensions/ad-blockers that strip query strings
  5. Confirm the xAI authorize endpoint is configured to return response_type=code
Defensive patterns

Strategy: try-catch

Validate before calling

// Before treating a callback as complete, confirm the code param exists.
const params = new URL(callbackUrl).searchParams;
if (!params.get('code') && !params.get('error')) {
  console.log('Callback missing authorization code — restart the flow.');
}

Try / catch

try {
  await xai.connect();
} catch (err) {
  if (err.message === 'No authorization code received') {
    // restart the OAuth flow; callback arrived without ?code=
  } else {
    throw err;
  }
}

Prevention

When it happens

Trigger: During xaiOAuthService.connect(), the local server receives a callback at the expected path whose query string is missing `code` entirely (callbackParams.code is falsy) while callbackParams.error is also unset.

Common situations: User closed the auth flow early or the browser hit the callback URL directly/manually; a proxy or browser extension stripped query parameters; redirect_uri/path mismatch so a page other than the real xAI callback hit the loopback server (e.g. another app bound to the same port answered first); xAI redirected with a fragment or POST body instead of a code query param.

Related errors


AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30). Data as JSON: /api/errors/70ff004596aa97f5. Report an issue: GitHub.