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'.

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.

Appendix: 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)