router-for-me/CLIProxyAPI · error
antigravity userinfo: request failed: status %d
Error message
antigravity userinfo: request failed: status %d
What it means
The userinfo endpoint returned a non-2xx status with an empty body. Most commonly 401 (access token invalid, expired, or revoked) or 403 (insufficient scope for userinfo), occasionally a 5xx with no body.
Source
Thrown at internal/auth/antigravity/auth.go:211
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)
}
}()
if resp.StatusCode < http.StatusOK || resp.StatusCode >= http.StatusMultipleChoices {
bodyBytes, errRead := io.ReadAll(io.LimitReader(resp.Body, 8<<10))
if errRead != nil {
return "", fmt.Errorf("antigravity userinfo: read response: %w", errRead)
}
body := strings.TrimSpace(string(bodyBytes))
if body == "" {
return "", fmt.Errorf("antigravity userinfo: request failed: status %d", resp.StatusCode)
}
return "", fmt.Errorf("antigravity userinfo: request failed: status %d: %s", resp.StatusCode, body)
}
var info userInfo
if errDecode := json.NewDecoder(resp.Body).Decode(&info); errDecode != nil {
return "", fmt.Errorf("antigravity userinfo: decode response: %w", errDecode)
}
email := strings.TrimSpace(info.Email)
if email == "" {
return "", fmt.Errorf("antigravity userinfo: response missing email")
}
return email, nil
}
// FetchProjectID retrieves the project ID for the authenticated user via loadCodeAssist
func (o *AntigravityAuth) FetchProjectID(ctx context.Context, accessToken string) (string, error) {
userAgent := o.shortUserAgent()
loadReqBody := map[string]any{View on GitHub (pinned to 78f0c4079e)
Solutions
- Retry with a freshly exchanged access token
- If using a stored token, refresh it first via the refresh-token flow
- Confirm the OAuth scopes requested during authorization include email access
Defensive patterns
Strategy: retry
Validate before calling
if time.Since(token.AcquiredAt) > time.Duration(token.ExpiresIn-30)*time.Second {
token = refreshAccessToken(token.RefreshToken)
}
email, err := auth.FetchUserInfo(ctx, token.AccessToken) Try / catch
if strings.Contains(err.Error(), "userinfo: request failed: status 401") {
// refresh the token, then retry once
} Prevention
- Fetch userinfo immediately after exchange
- Honor expires_in and refresh before use
- Request the email scope up front
When it happens
Trigger: Calling FetchUserInfo with a token that expired or was revoked; using a token from a different flow/client; Google userinfo outage.
Common situations: Fetching user info long after the exchange completed; token stored and reused across process restarts after expiry; scopes not including email/profile.
Related errors
- antigravity token exchange: request failed: status %d
- antigravity token exchange: request failed: status %d: %s
- antigravity userinfo: missing access token
- antigravity userinfo: request failed: status %d: %s
- request failed with status %d: %s
AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15).
Data as JSON: /api/errors/514a242b81038f2f.
Report an issue: GitHub.