router-for-me/CLIProxyAPI · error
antigravity userinfo: missing access token
Error message
antigravity userinfo: missing access token
What it means
FetchUserInfo was called with an access token that is empty after trimming whitespace. This is a caller-side validation failure before any HTTP request is made — the token passed in was "", whitespace-only, or never populated.
Source
Thrown at internal/auth/antigravity/auth.go:185
body := strings.TrimSpace(string(bodyBytes))
if body == "" {
return nil, fmt.Errorf("antigravity token exchange: request failed: status %d", resp.StatusCode)
}
return nil, fmt.Errorf("antigravity token exchange: request failed: status %d: %s", resp.StatusCode, body)
}
var token TokenResponse
if errDecode := json.NewDecoder(resp.Body).Decode(&token); errDecode != nil {
return nil, fmt.Errorf("antigravity token exchange: decode response: %w", errDecode)
}
return &token, nil
}
// FetchUserInfo retrieves user email from Google
func (o *AntigravityAuth) FetchUserInfo(ctx context.Context, accessToken string) (string, error) {
accessToken = strings.TrimSpace(accessToken)
if accessToken == "" {
return "", fmt.Errorf("antigravity userinfo: missing access token")
}
req, err := http.NewRequestWithContext(ctx, http.MethodGet, UserInfoEndpoint, nil)
if err != nil {
return "", fmt.Errorf("antigravity userinfo: create request: %w", err)
}
req.Header.Set("Authorization", "Bearer "+accessToken)
req.Header.Set("User-Agent", o.shortUserAgent())
resp, errDo := o.httpClient.Do(req)
if errDo != nil {
return "", fmt.Errorf("antigravity userinfo: execute request: %w", errDo)
}
defer func() {
if errClose := resp.Body.Close(); errClose != nil {
log.Errorf("antigravity userinfo: close body error: %v", errClose)
}
}()
View on GitHub (pinned to 78f0c4079e)
Solutions
- Complete ExchangeCodeForTokens first and check its error before fetching user info
- Verify the field you pass actually carries the token (log its length, never the value)
- Add a guard at the call site to skip the userinfo step when the token is empty
Example fix
// before
email, err := auth.FetchUserInfo(ctx, token.AccessToken)
// after
if token == nil || strings.TrimSpace(token.AccessToken) == "" {
return errors.New("cannot fetch userinfo: no access token")
}
email, err := auth.FetchUserInfo(ctx, token.AccessToken) Defensive patterns
Strategy: validation
Validate before calling
if token == nil || strings.TrimSpace(token.AccessToken) == "" {
return errors.New("skip userinfo: no access token")
}
email, err := auth.FetchUserInfo(ctx, token.AccessToken) Type guard
func hasAccessToken(t *TokenResponse) bool {
return t != nil && strings.TrimSpace(t.AccessToken) != ""
} Prevention
- Check the exchange result before any userinfo call
- Guard zero-value structs at the call site
When it happens
Trigger: Calling FetchUserInfo with an empty string; passing TokenResponse.AccessToken from a zero-value struct; token field name typo (e.g. accessToken vs access_token) leaving the variable empty.
Common situations: Calling userinfo before completing the token exchange; nil-check missed on the TokenResponse pointer and reading its zero-value field; a test calling with an unset fixture value.
Related errors
- antigravity userinfo: request failed: status %d
- antigravity token exchange: create request: %w
- antigravity token exchange: execute request: %w
- antigravity token exchange: read response: %w
- antigravity token exchange: request failed: status %d
AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15).
Data as JSON: /api/errors/ce3aff49d29a840e.
Report an issue: GitHub.