{"record":{"id":"c522ba10e5eedb20","repo":"router-for-me/CLIProxyAPI","slug":"antigravity-userinfo-read-response-w","errorCode":null,"errorMessage":"antigravity userinfo: read response: %w","messagePattern":"antigravity userinfo: read response: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/auth/antigravity/auth.go","lineNumber":207,"sourceCode":"\t\treturn \"\", fmt.Errorf(\"antigravity userinfo: create request: %w\", err)\n\t}\n\treq.Header.Set(\"Authorization\", \"Bearer \"+accessToken)\n\treq.Header.Set(\"User-Agent\", o.shortUserAgent())\n\n\tresp, errDo := o.httpClient.Do(req)\n\tif errDo != nil {\n\t\treturn \"\", fmt.Errorf(\"antigravity userinfo: execute request: %w\", errDo)\n\t}\n\tdefer func() {\n\t\tif errClose := resp.Body.Close(); errClose != nil {\n\t\t\tlog.Errorf(\"antigravity userinfo: 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 \"\", fmt.Errorf(\"antigravity userinfo: read response: %w\", errRead)\n\t\t}\n\t\tbody := strings.TrimSpace(string(bodyBytes))\n\t\tif body == \"\" {\n\t\t\treturn \"\", fmt.Errorf(\"antigravity userinfo: request failed: status %d\", resp.StatusCode)\n\t\t}\n\t\treturn \"\", fmt.Errorf(\"antigravity userinfo: request failed: status %d: %s\", resp.StatusCode, body)\n\t}\n\tvar info userInfo\n\tif errDecode := json.NewDecoder(resp.Body).Decode(&info); errDecode != nil {\n\t\treturn \"\", fmt.Errorf(\"antigravity userinfo: decode response: %w\", errDecode)\n\t}\n\temail := strings.TrimSpace(info.Email)\n\tif email == \"\" {\n\t\treturn \"\", fmt.Errorf(\"antigravity userinfo: response missing email\")\n\t}\n\treturn email, nil\n}\n","sourceCodeStart":189,"sourceCodeEnd":225,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/internal/auth/antigravity/auth.go#L189-L225","documentation":"Userinfo returned a non-2xx status and reading its (8 KiB-limited) body failed. The response started but the body read was interrupted — connection reset, truncation, or context cancellation between headers and body.","triggerScenarios":"Google responds 401/403 then resets the connection; context deadline hits while streaming the error body; intermediary truncates the response.","commonSituations":"Tight timeouts that cover only the header round-trip; unstable networks during auth.","solutions":["Increase the context/httpClient timeout to cover full body reads","Retry the idempotent userinfo request","Include resp.StatusCode in logs to know what the server was reporting even without the body"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"if strings.Contains(err.Error(), \"userinfo: read response\") {\n\t// body interrupted; retry the idempotent GET\n}","preventionTips":["Set timeouts covering full body reads","Retry userinfo on truncation — it is read-only"],"tags":["oauth","antigravity","network","response-body"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}