decolua/9router · error · Error

No authorization code received

Error message

No authorization code received

What it means

After the local callback server receives a redirect during Gemini OAuth, connect() expects a `code` query parameter containing the authorization code. If the callback params contain neither an `error` nor a `code`, this "No authorization code received" error is thrown at gemini.js:209. It indicates the callback arrived but the OAuth handshake did not deliver what the flow requires.

Source

Thrown at src/lib/oauth/services/gemini.js:209

        }, 300000);

        const checkInterval = setInterval(() => {
          if (callbackParams) {
            clearInterval(checkInterval);
            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");
      }

      spinner.start("Exchanging code for tokens...");

      // Exchange code for tokens
      const tokens = await this.exchangeCode(callbackParams.code, redirectUri);

      spinner.text = "Fetching user info...";

      // Get user info
      const userInfo = await this.getUserInfo(tokens.access_token);

      spinner.text = "Fetching project ID...";

      // Fetch project ID
      const projectId = await this.fetchProjectId(tokens.access_token);

      spinner.text = "Saving tokens to server...";

View on GitHub (pinned to 90b52e06ff)

Solutions

  1. Re-run the connect flow and let the browser complete the Google authorization without manual edits to the URL.
  2. Close stale tabs pointing at the localhost callback port, then retry so only the fresh redirect hits the server.
  3. Disable extensions that rewrite or strip URLs (privacy/ad blockers) or try another browser for the auth step.
  4. Ensure you are completing the full consent flow and landing back on the callback page automatically, not copying parts of the URL.
Defensive patterns

Strategy: validation

Validate before calling

function hasAuthCode(params) {
  return params && typeof params.code === 'string' && params.code.length > 0;
}
// before proceeding: if (!hasAuthCode(callbackParams)) restart the flow instead of continuing;

Type guard

function hasAuthorizationCode(params) {
  return params !== null && typeof params === 'object' && 'code' in params && typeof params.code === 'string';
}

Try / catch

try {
  await geminiService.connect();
} catch (err) {
  if (err.message === 'No authorization code received') {
    console.error('Callback arrived without an authorization code — close stale localhost callback tabs and rerun the connect flow.');
  }
  throw err;
}

Prevention

When it happens

Trigger: The redirect to http://localhost:<port>/callback arrived with an empty or unexpected query string — e.g. the user manually navigated to the callback URL, the browser truncated the query params, a redirect loop dropped `code`, or Google redirected for a non-error reason without a code.

Common situations: User reloaded or bookmarked the localhost:port/callback URL in the browser while the CLI was waiting; a browser extension or privacy tool stripped query parameters; a misconfigured redirect served the callback page without forwarding the OAuth query string.

Related errors


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