slopus/happy · error

No authorization code received

Error message

No authorization code received

What it means

After the state check, the Gemini callback server requires a `code` query parameter on the /oauth2callback redirect; this code is exchanged at https://oauth2.googleapis.com/token for access/refresh tokens. If the redirect carries no `code` (Google instead appends an `error` parameter, which is checked earlier, or the parameter is missing entirely), the server responds 400 and rejects with 'No authorization code received'.

Source

Thrown at packages/happy-cli/src/commands/connect/authenticateGemini.ts:152

                    res.writeHead(302, { 
                        'Location': 'https://developers.google.com/gemini-code-assist/auth_failure_gemini' 
                    });
                    res.end();
                    server.close();
                    reject(new Error(`Authentication error: ${error}`));
                    return;
                }
                
                if (receivedState !== state) {
                    res.writeHead(400);
                    res.end('State mismatch. Possible CSRF attack');
                    server.close();
                    reject(new Error('Invalid state parameter'));
                    return;
                }
                
                if (!code) {
                    res.writeHead(400);
                    res.end('No authorization code received');
                    server.close();
                    reject(new Error('No authorization code received'));
                    return;
                }
                
                try {
                    // Exchange code for tokens
                    const tokens = await exchangeCodeForTokens(code, verifier, port);
                    
                    // Redirect to success page
                    res.writeHead(302, { 
                        'Location': 'https://developers.google.com/gemini-code-assist/auth_success_gemini' 
                    });
                    res.end();
                    
                    server.close();
                    resolve(tokens);

View on GitHub (pinned to b824cd0a46)

Solutions

  1. Inspect the callback URL in the browser for `error=` or `error_subtype=` parameters (e.g. access_denied) to learn why Google withheld the code.
  2. Rerun `happy` connect and complete the Google consent screen fully, granting the requested cloud-platform/email/profile scopes.
  3. Retry from scratch — authorization codes are single-use and short-lived; don't reload a callback URL.
  4. Verify nothing (proxy, extension, manual editing) strips the `code` query parameter from the localhost redirect.
Defensive patterns

Strategy: try-catch

Try / catch

try {
  const tokens = await authenticateGemini();
} catch (err) {
  if (err instanceof Error && err.message === 'No authorization code received') {
    // consent denied or provider withheld the code — surface guidance and retry
    console.error('Google did not return an authorization code (likely denied consent or redirect_uri mismatch). Retry connect and approve all scopes.');
  } else throw err;
}

Prevention

When it happens

Trigger: Google redirects to /oauth2callback with matching state but without `code` — the consent screen was dismissed in a way that bypasses the `error` branch, the authorization request was rejected (unregistered redirect_uri, missing scope approval), or the callback URL was manually edited/stripped.

Common situations: User aborts the Google consent dialog; the Google Cloud OAuth client's authorized redirect URI doesn't include http://localhost:<port>/oauth2callback; `prompt=consent` flow interrupted; single-use code consumed by an earlier request so Google re-redirects without one.

Related errors


AI-assisted analysis of slopus/happy@b824cd0a46 (2026-08-31). Data as JSON: /api/errors/257f5ed77305a9d1. Report an issue: GitHub.