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

  1. Retry with a freshly exchanged access token
  2. If using a stored token, refresh it first via the refresh-token flow
  3. 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

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


AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15). Data as JSON: /api/errors/514a242b81038f2f. Report an issue: GitHub.