{"record":{"id":"1b5094d28d9e12c1","repo":"router-for-me/CLIProxyAPI","slug":"antigravity-userinfo-decode-response-w","errorCode":null,"errorMessage":"antigravity userinfo: decode response: %w","messagePattern":"antigravity userinfo: decode response: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/auth/antigravity/auth.go","lineNumber":217,"sourceCode":"\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\n// FetchProjectID retrieves the project ID for the authenticated user via loadCodeAssist\nfunc (o *AntigravityAuth) FetchProjectID(ctx context.Context, accessToken string) (string, error) {\n\tuserAgent := o.shortUserAgent()\n\tloadReqBody := map[string]any{\n\t\t\"metadata\": antigravityLoadCodeAssistMetadata(),\n\t}\n\n\trawBody, errMarshal := json.Marshal(loadReqBody)\n\tif errMarshal != nil {\n\t\treturn \"\", fmt.Errorf(\"marshal request body: %w\", errMarshal)","sourceCodeStart":199,"sourceCodeEnd":235,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/internal/auth/antigravity/auth.go#L199-L235","documentation":"Userinfo returned 2xx but the body could not be decoded into the userInfo struct. The response was not the expected JSON object — possibly empty, HTML, or a changed schema — so fields like email could not be extracted.","triggerScenarios":"Empty 200 body; proxy replacing the response with HTML; Google changing the userinfo response shape; body truncated by a timeout mid-decode.","commonSituations":"Interception on the userinfo host; flaky networks truncating responses.","solutions":["Log the raw body prefix on decode failure to identify interception or schema drift","Bypass or trust the intercepting proxy and retry","If the schema changed, update the userInfo struct's json tags"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if !json.Valid(rawPrefix) {\n\t// interception/truncation — retry the userinfo GET\n}","typeGuard":null,"tryCatchPattern":"var syntaxErr *json.SyntaxError\nif errors.As(err, &syntaxErr) {\n\t// body not JSON — proxy or outage; retry or bypass proxy\n}","preventionTips":["Verify Content-Type: application/json on 2xx userinfo responses","Detect HTML bodies from intercepting proxies before decode"],"tags":["oauth","antigravity","json","response-body"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}