router-for-me/CLIProxyAPI · error
antigravity token exchange: create request: %w
Error message
antigravity token exchange: create request: %w
What it means
The Antigravity OAuth token exchange failed at request construction: http.NewRequestWithContext rejected the inputs. With a fixed POST this almost always means the TokenEndpoint URL constant is malformed, or the context is already cancelled (Go 1.20+ reports an invalid context at NewRequest time).
Source
Thrown at internal/auth/antigravity/auth.go:148
params.Set("redirect_uri", redirectURI)
params.Set("response_type", "code")
params.Set("scope", strings.Join(Scopes, " "))
params.Set("state", state)
return AuthEndpoint + "?" + params.Encode()
}
// ExchangeCodeForTokens exchanges authorization code for access and refresh tokens
func (o *AntigravityAuth) ExchangeCodeForTokens(ctx context.Context, code, redirectURI string) (*TokenResponse, error) {
data := url.Values{}
data.Set("code", code)
data.Set("client_id", ClientID)
data.Set("client_secret", ClientSecret)
data.Set("redirect_uri", redirectURI)
data.Set("grant_type", "authorization_code")
req, err := http.NewRequestWithContext(ctx, http.MethodPost, TokenEndpoint, strings.NewReader(data.Encode()))
if err != nil {
return nil, fmt.Errorf("antigravity token exchange: create request: %w", err)
}
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
resp, errDo := o.httpClient.Do(req)
if errDo != nil {
return nil, fmt.Errorf("antigravity token exchange: execute request: %w", errDo)
}
defer func() {
if errClose := resp.Body.Close(); errClose != nil {
log.Errorf("antigravity token exchange: 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 nil, fmt.Errorf("antigravity token exchange: read response: %w", errRead)
}View on GitHub (pinned to 78f0c4079e)
Solutions
- Check whether the ctx passed to ExchangeCodeForTokens derives from an already-finished HTTP request; use a fresh context.Background() with a timeout for the exchange
- Verify TokenEndpoint is a valid absolute URL
- Update Go version to get clearer context-related error messages if on an old release
Example fix
// before ctx := r.Context() // callback request context, may be cancelled tokens, err := auth.ExchangeCodeForTokens(ctx, code, redirect) // after ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() tokens, err := auth.ExchangeCodeForTokens(ctx, code, redirect)
Defensive patterns
Strategy: validation
Validate before calling
if ctx.Err() != nil {
return ctx.Err()
}
tokens, err := auth.ExchangeCodeForTokens(ctx, code, redirect) Try / catch
if _, err := auth.ExchangeCodeForTokens(ctx, code, redirect); err != nil {
if strings.Contains(err.Error(), "create request") {
// context or endpoint problem — restart flow with fresh context
}
} Prevention
- Use a fresh context.Background() with timeout for OAuth exchange, not a callback request context
- Validate endpoint URL constants at startup
When it happens
Trigger: Building the POST to TokenEndpoint with a nil or already-cancelled/expired context; TokenEndpoint constant corrupted (spaces, bad scheme) via code change or build flags.
Common situations: OAuth callback handler passing a request context that was cancelled when the callback request disconnected; upstream constant change in a fork.
Related errors
- antigravity token exchange: execute request: %w
- antigravity token exchange: read response: %w
- antigravity userinfo: create request: %w
- antigravity userinfo: execute request: %w
- antigravity userinfo: read response: %w
AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15).
Data as JSON: /api/errors/e1ee91fb64071a26.
Report an issue: GitHub.