{"record":{"id":"cacd141fc8eb850d","repo":"router-for-me/CLIProxyAPI","slug":"kimi-failed-to-read-token-response-w","errorCode":null,"errorMessage":"kimi: failed to read token response: %w","messagePattern":"kimi: failed to read token response: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/auth/kimi/kimi.go","lineNumber":295,"sourceCode":"\treq.Header.Set(\"Content-Type\", \"application/x-www-form-urlencoded\")\n\treq.Header.Set(\"Accept\", \"application/json\")\n\tfor k, v := range c.commonHeaders() {\n\t\treq.Header.Set(k, v)\n\t}\n\n\tresp, err := c.httpClient.Do(req)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"kimi: token request failed: %w\", err), false\n\t}\n\tdefer func() {\n\t\tif errClose := resp.Body.Close(); errClose != nil {\n\t\t\tlog.Errorf(\"kimi token exchange: close body error: %v\", errClose)\n\t\t}\n\t}()\n\n\tbodyBytes, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"kimi: failed to read token response: %w\", err), false\n\t}\n\n\t// Parse response - Kimi returns 200 for both success and pending states\n\tvar oauthResp struct {\n\t\tError            string  `json:\"error\"`\n\t\tErrorDescription string  `json:\"error_description\"`\n\t\tAccessToken      string  `json:\"access_token\"`\n\t\tRefreshToken     string  `json:\"refresh_token\"`\n\t\tTokenType        string  `json:\"token_type\"`\n\t\tExpiresIn        float64 `json:\"expires_in\"`\n\t\tScope            string  `json:\"scope\"`\n\t}\n\n\tif err = json.Unmarshal(bodyBytes, &oauthResp); err != nil {\n\t\treturn nil, fmt.Errorf(\"kimi: failed to parse token response: %w\", err), false\n\t}\n\n\tif oauthResp.Error != \"\" {","sourceCodeStart":277,"sourceCodeEnd":313,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/internal/auth/kimi/kimi.go#L277-L313","documentation":"The token endpoint returned headers successfully but io.ReadAll of its body failed mid-stream during a polling tick. Same class as a body read failure on the device-code request, but occurring on POST /api/oauth/token; it aborts the polling loop (shouldContinue=false).","triggerScenarios":"Connection reset between response headers and body on the token endpoint, proxy or load balancer cutting the stream, truncated chunked encoding from auth.kimi.com.","commonSituations":"Flaky networks during the multi-minute authorization wait, mobile tethers, corporate proxies with short idle/stream timeouts.","solutions":["Re-run the login flow — a fresh device code and new connections usually clear it","Check for proxy interference on auth.kimi.com and bypass it","If reproducible every time, capture with curl -i to see whether the body is consistently truncated (server-side issue)"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"failed to read token response\") {\n    // restart login; single read failure aborts the poll loop\n}","preventionTips":["Avoid networks with aggressive stream idle timeouts during login","Restart the flow on any mid-body read failure"],"tags":["kimi","oauth","device-flow","network","http"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}