{"record":{"id":"24aaf5ca0848cf66","repo":"router-for-me/CLIProxyAPI","slug":"token-exchange-request-failed-w-24aaf5","errorCode":null,"errorMessage":"token exchange request failed: %w","messagePattern":"token exchange request failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/auth/codex/openai_auth.go","lineNumber":126,"sourceCode":"\tdata := url.Values{\n\t\t\"grant_type\":    {\"authorization_code\"},\n\t\t\"client_id\":     {ClientID},\n\t\t\"code\":          {code},\n\t\t\"redirect_uri\":  {strings.TrimSpace(redirectURI)},\n\t\t\"code_verifier\": {pkceCodes.CodeVerifier},\n\t}\n\n\treq, err := http.NewRequestWithContext(ctx, \"POST\", TokenURL, strings.NewReader(data.Encode()))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create token request: %w\", err)\n\t}\n\n\treq.Header.Set(\"Content-Type\", \"application/x-www-form-urlencoded\")\n\treq.Header.Set(\"Accept\", \"application/json\")\n\n\tresp, err := o.httpClient.Do(req)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"token exchange request failed: %w\", err)\n\t}\n\tdefer func() {\n\t\t_ = resp.Body.Close()\n\t}()\n\n\tbody, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to read token response: %w\", err)\n\t}\n\t// log.Debugf(\"Token response: %s\", string(body))\n\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn nil, fmt.Errorf(\"token exchange failed with status %d: %s\", resp.StatusCode, string(body))\n\t}\n\n\t// Parse token response\n\tvar tokenResp struct {\n\t\tAccessToken  string `json:\"access_token\"`","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/internal/auth/codex/openai_auth.go#L108-L144","documentation":"The HTTP round trip for the Codex token exchange (POST to TokenURL) failed at the transport level — DNS, TCP connect, TLS handshake, or mid-request disconnect. The request was built successfully; the error comes from httpClient.Do and is wrapped verbatim, so the underlying cause (dial tcp, x509, proxyconnect, etc.) is visible in the wrapped message.","triggerScenarios":"No internet or DNS failure resolving the OpenAI auth host; TLS interception by a corporate proxy with an untrusted CA; HTTP(S)_PROXY env var pointing at a dead proxy; connection reset by a firewall between the host and the token endpoint; context canceled while the request was in flight.","commonSituations":"Running login behind corporate proxy/VPN without configuring the proxy CA; egress firewall blocking the auth domain; flaky network during interactive login; HTTPS_PROXY misconfigured in the shell where cli-proxy-api runs.","solutions":["Inspect the wrapped error text to identify the layer (DNS, TLS, proxy, reset) before changing anything.","Test reachability: `curl -v <TokenURL>` from the same machine and user.","If behind a TLS-intercepting proxy, trust its CA cert or set SSL_CERT_FILE/SSL_CERT_DIR.","Fix or unset HTTP_PROXY/HTTPS_PROXY/NO_PROXY for the login process.","Retry the login once network is confirmed working — transient resets are common."],"exampleFix":"// before: default client, no proxy awareness\nresp, err := o.httpClient.Do(req)\n\n// after: ensure the client honors the environment and retries transport errors\ntransport := &http.Transport{ Proxy: http.ProxyFromEnvironment }\no.httpClient = &http.Client{ Transport: transport, Timeout: 30 * time.Second }","handlingStrategy":"retry","validationCode":"// Pre-flight: confirm the token endpoint resolves and is reachable\nif _, err := net.DialTimeout(\"tcp\", \"auth.openai.com:443\", 5*time.Second); err != nil {\n    return fmt.Errorf(\"token endpoint unreachable, fix network first: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"tok, err := auth.ExchangeCode(ctx, code)\nif err != nil {\n    var netErr net.Error\n    if errors.As(err, &netErr) || strings.Contains(err.Error(), \"dial\") || strings.Contains(err.Error(), \"proxy\") {\n        // transient transport failure: safe to restart the login flow later\n        log.Warnf(\"network error during exchange: %v\", err)\n    }\n    return err\n}","preventionTips":["Configure proxy env vars correctly before starting login.","Trust corporate CA certs via SSL_CERT_FILE when behind TLS interception.","Keep the login context deadline generous (minutes) to survive slow networks."],"tags":["network","oauth","codex","proxy","tls","auth-flow"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}