{"record":{"id":"e1ee91fb64071a26","repo":"router-for-me/CLIProxyAPI","slug":"antigravity-token-exchange-create-request-w","errorCode":null,"errorMessage":"antigravity token exchange: create request: %w","messagePattern":"antigravity token exchange: create request: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/auth/antigravity/auth.go","lineNumber":148,"sourceCode":"\tparams.Set(\"redirect_uri\", redirectURI)\n\tparams.Set(\"response_type\", \"code\")\n\tparams.Set(\"scope\", strings.Join(Scopes, \" \"))\n\tparams.Set(\"state\", state)\n\treturn AuthEndpoint + \"?\" + params.Encode()\n}\n\n// ExchangeCodeForTokens exchanges authorization code for access and refresh tokens\nfunc (o *AntigravityAuth) ExchangeCodeForTokens(ctx context.Context, code, redirectURI string) (*TokenResponse, error) {\n\tdata := url.Values{}\n\tdata.Set(\"code\", code)\n\tdata.Set(\"client_id\", ClientID)\n\tdata.Set(\"client_secret\", ClientSecret)\n\tdata.Set(\"redirect_uri\", redirectURI)\n\tdata.Set(\"grant_type\", \"authorization_code\")\n\n\treq, err := http.NewRequestWithContext(ctx, http.MethodPost, TokenEndpoint, strings.NewReader(data.Encode()))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"antigravity token exchange: create request: %w\", err)\n\t}\n\treq.Header.Set(\"Content-Type\", \"application/x-www-form-urlencoded\")\n\n\tresp, errDo := o.httpClient.Do(req)\n\tif errDo != nil {\n\t\treturn nil, fmt.Errorf(\"antigravity token exchange: execute request: %w\", errDo)\n\t}\n\tdefer func() {\n\t\tif errClose := resp.Body.Close(); errClose != nil {\n\t\t\tlog.Errorf(\"antigravity token exchange: close body error: %v\", errClose)\n\t\t}\n\t}()\n\n\tif resp.StatusCode < http.StatusOK || resp.StatusCode >= http.StatusMultipleChoices {\n\t\tbodyBytes, errRead := io.ReadAll(io.LimitReader(resp.Body, 8<<10))\n\t\tif errRead != nil {\n\t\t\treturn nil, fmt.Errorf(\"antigravity token exchange: read response: %w\", errRead)\n\t\t}","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/internal/auth/antigravity/auth.go#L130-L166","documentation":"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).","triggerScenarios":"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.","commonSituations":"OAuth callback handler passing a request context that was cancelled when the callback request disconnected; upstream constant change in a fork.","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"],"exampleFix":"// before\nctx := r.Context() // callback request context, may be cancelled\ntokens, err := auth.ExchangeCodeForTokens(ctx, code, redirect)\n\n// after\nctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)\ndefer cancel()\ntokens, err := auth.ExchangeCodeForTokens(ctx, code, redirect)","handlingStrategy":"validation","validationCode":"if ctx.Err() != nil {\n\treturn ctx.Err()\n}\ntokens, err := auth.ExchangeCodeForTokens(ctx, code, redirect)","typeGuard":null,"tryCatchPattern":"if _, err := auth.ExchangeCodeForTokens(ctx, code, redirect); err != nil {\n\tif strings.Contains(err.Error(), \"create request\") {\n\t\t// context or endpoint problem — restart flow with fresh context\n\t}\n}","preventionTips":["Use a fresh context.Background() with timeout for OAuth exchange, not a callback request context","Validate endpoint URL constants at startup"],"tags":["oauth","antigravity","network","context"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}