{"record":{"id":"0f91858655ea2ef9","repo":"router-for-me/CLIProxyAPI","slug":"fetch-claude-oauth-s-w","errorCode":null,"errorMessage":"fetch Claude OAuth %s: %w","messagePattern":"fetch Claude OAuth (.+?): %w","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/auth/claude/anthropic_auth.go","lineNumber":243,"sourceCode":"func (o *ClaudeAuth) fetchOAuthControlPlaneJSON(ctx context.Context, endpoint, accessToken, label string) ([]byte, error) {\n\tif o == nil || o.httpClient == nil {\n\t\treturn nil, fmt.Errorf(\"fetch Claude OAuth %s: HTTP client is nil\", label)\n\t}\n\taccessToken = strings.TrimSpace(accessToken)\n\tif accessToken == \"\" {\n\t\treturn nil, fmt.Errorf(\"fetch Claude OAuth %s: access token is empty\", label)\n\t}\n\treq, errRequest := http.NewRequestWithContext(ctx, http.MethodGet, endpoint, nil)\n\tif errRequest != nil {\n\t\treturn nil, fmt.Errorf(\"create Claude OAuth %s request: %w\", label, errRequest)\n\t}\n\tapplyClaudeOAuthAxiosHeaders(req)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+accessToken)\n\treq.Header.Set(\"Cache-Control\", \"no-cache\")\n\n\tresp, errDo := o.httpClient.Do(req)\n\tif errDo != nil {\n\t\treturn nil, fmt.Errorf(\"fetch Claude OAuth %s: %w\", label, errDo)\n\t}\n\tdefer func() {\n\t\tif errClose := resp.Body.Close(); errClose != nil {\n\t\t\tlog.Errorf(\"failed to close Claude OAuth %s response body: %v\", label, errClose)\n\t\t}\n\t}()\n\tbody, errRead := readClaudeOAuthResponseBody(resp)\n\tif errRead != nil {\n\t\treturn nil, fmt.Errorf(\"read Claude OAuth %s response: %w\", label, errRead)\n\t}\n\tif resp.StatusCode < http.StatusOK || resp.StatusCode >= http.StatusMultipleChoices {\n\t\treturn nil, fmt.Errorf(\"fetch Claude OAuth %s failed with status %d\", label, resp.StatusCode)\n\t}\n\treturn body, nil\n}\n\n// FetchOAuthProfile retrieves the account identity associated with an OAuth access token.\nfunc (o *ClaudeAuth) FetchOAuthProfile(ctx context.Context, accessToken string) (*OAuthProfile, error) {","sourceCodeStart":225,"sourceCodeEnd":261,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/internal/auth/claude/anthropic_auth.go#L225-L261","documentation":"Returned by ClaudeAuth.fetchOAuthControlPlaneJSON when the GET to the Anthropic OAuth control-plane endpoint fails at the transport level, wrapping the httpClient.Do error. The request is deliberately Axios-shaped (User-Agent axios/1.15.2, Accept-Encoding including br, Connection: close) to mirror Claude Code's client; intermediaries that filter on such headers, plus ordinary DNS/TLS/proxy failures, land here. A nil-body or non-2xx outcome does NOT — those are separate errors.","triggerScenarios":"api.anthropic.com unreachable (DNS/firewall); TLS interception rejecting the connection; proxy misconfiguration applied via util.SetProxy; ctx cancelled during the request; an intermediary resetting connections flagged as non-browser traffic.","commonSituations":"Corporate proxies blocking api.anthropic.com; Great-Firewall-style regional interference; transient Anthropic outages; VPN split-tunneling excluding the API host.","solutions":["Unwrap with errors.As to *url.Error and identify DNS vs dial vs TLS vs context.Canceled","Test reachability with curl -v https://api.anthropic.com/api/oauth/profile from the same environment","Fix proxy settings in config.yaml or bypass the intercepting middlebox","Retry after checking https://status.anthropic.com for outages"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"profile, err := auth.FetchOAuthProfile(ctx, token)\nif err != nil {\n    var urlErr *url.Error\n    if errors.As(err, &urlErr) && !errors.Is(urlErr.Err, context.Canceled) {\n        profile, err = retryWithBackoff(func() (*OAuthProfile, error) {\n            return auth.FetchOAuthProfile(ctx, token)\n        })\n    }\n    if err != nil { return err }\n}","preventionTips":["Pre-flight check connectivity to api.anthropic.com before starting login","Validate proxy-server settings; transport errors here often come from proxy config","Check Anthropic status page before retrying during suspected outages"],"tags":["claude","network","proxy","tls","oauth"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}