{"record":{"id":"bd103ce93e6bcda2","repo":"router-for-me/CLIProxyAPI","slug":"decode-claude-oauth-gzip-response-w","errorCode":null,"errorMessage":"decode Claude OAuth gzip response: %w","messagePattern":"decode Claude OAuth gzip response: %w","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/auth/claude/oauth_response.go","lineNumber":46,"sourceCode":"\t\tif encoding == \"\" || encoding == \"identity\" {\n\t\t\tcontinue\n\t\t}\n\t\tvar errDecode error\n\t\tencoded, errDecode = decodeClaudeOAuthEncoding(encoded, encoding)\n\t\tif errDecode != nil {\n\t\t\treturn nil, errDecode\n\t\t}\n\t}\n\treturn encoded, nil\n}\n\nfunc decodeClaudeOAuthEncoding(encoded []byte, encoding string) ([]byte, error) {\n\tvar reader io.ReadCloser\n\tswitch encoding {\n\tcase \"gzip\":\n\t\tgzipReader, errGzip := gzip.NewReader(bytes.NewReader(encoded))\n\t\tif errGzip != nil {\n\t\t\treturn nil, fmt.Errorf(\"decode Claude OAuth gzip response: %w\", errGzip)\n\t\t}\n\t\treader = gzipReader\n\tcase \"deflate\":\n\t\tzlibReader, errZlib := zlib.NewReader(bytes.NewReader(encoded))\n\t\tif errZlib == nil {\n\t\t\treader = zlibReader\n\t\t} else {\n\t\t\treader = flate.NewReader(bytes.NewReader(encoded))\n\t\t}\n\tcase \"br\":\n\t\treader = io.NopCloser(brotli.NewReader(bytes.NewReader(encoded)))\n\tcase \"compress\":\n\t\treader = lzw.NewReader(bytes.NewReader(encoded), lzw.MSB, 8)\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"decode Claude OAuth response: unsupported content encoding %q\", encoding)\n\t}\n\tdecoded, errDecoded := io.ReadAll(reader)\n\tif errDecoded != nil {","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/internal/auth/claude/oauth_response.go#L28-L64","documentation":"decodeClaudeOAuthEncoding decodes the Claude OAuth token-endpoint response according to its Content-Encoding header. This variant fires when the header says gzip but gzip.NewReader cannot parse the body, meaning the bytes are not a valid gzip stream. Typical causes are a truncated body, a plain-text body mislabeled as gzip, or an intermediary (proxy) mangling the response.","triggerScenarios":"POST to the Claude OAuth token/refresh endpoint returns Content-Encoding: gzip with a body that is corrupt, truncated (connection cut mid-read), or actually uncompressed; a corporate proxy or captive portal rewrites the response and breaks the gzip framing.","commonSituations":"Intercepting proxies (mitmproxy, Zscaler, corporate TLS inspection) that decode and re-encode bodies incorrectly; flaky networks truncating responses; servers that send identity bodies with a stale gzip header under load; local replay/snapshot test fixtures recorded without the gzip bytes.","solutions":["Retry the token request once — transient truncation and proxy interference often clear on the second attempt.","Disable compression on the OAuth client by sending Accept-Encoding: identity so the server returns an uncompressed body.","Bypass or correctly configure the intercepting proxy for the Anth OAuth host (api.anthropic.com / console.anthropic.com).","Capture the raw response bytes and verify with `curl --compressed` whether the server or the proxy is producing the bad gzip stream."],"exampleFix":"// before\nreq.Header.Set(\"Accept-Encoding\", \"gzip\")\n\n// after\nreq.Header.Set(\"Accept-Encoding\", \"identity\") // let the server skip compression","handlingStrategy":"retry","validationCode":"req.Header.Set(\"Accept-Encoding\", \"identity\") // sidestep gzip entirely","typeGuard":null,"tryCatchPattern":"var decodeErr error\nfor attempt := 0; attempt < 2; attempt++ {\n    body, decodeErr = claude.DecodeOAuthResponse(resp)\n    if decodeErr == nil { break }\n    if !strings.Contains(decodeErr.Error(), \"gzip\") { break }\n    time.Sleep(time.Second)\n}","preventionTips":["Request identity encoding for OAuth token endpoints to avoid decompression entirely.","Exclude OAuth hosts from TLS-inspecting proxies."],"tags":["claude","oauth","network","gzip","encoding"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}