{"record":{"id":"49da8608ed99db03","repo":"chenhg5/cc-connect","slug":"gemini-stt-read-response-w","errorCode":null,"errorMessage":"gemini stt: read response: %w","messagePattern":"gemini stt: read response: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/speech.go","lineNumber":273,"sourceCode":"\t}\n\n\tapiURL := fmt.Sprintf(\"%s/models/%s:generateContent\", g.BaseURL, url.PathEscape(g.Model))\n\treq, err := http.NewRequestWithContext(ctx, http.MethodPost, apiURL, bytes.NewReader(jsonData))\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"gemini stt: create request: %w\", err)\n\t}\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\treq.Header.Set(\"x-goog-api-key\", g.APIKey)\n\n\tresp, err := g.Client.Do(req)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"gemini stt: request: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\tbody, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"gemini stt: read response: %w\", err)\n\t}\n\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn \"\", fmt.Errorf(\"gemini stt API %d: %s\", resp.StatusCode, string(body))\n\t}\n\n\tvar result struct {\n\t\tCandidates []struct {\n\t\t\tContent struct {\n\t\t\t\tParts []struct {\n\t\t\t\t\tText string `json:\"text\"`\n\t\t\t\t} `json:\"parts\"`\n\t\t\t} `json:\"content\"`\n\t\t} `json:\"candidates\"`\n\t}\n\tif err := json.Unmarshal(body, &result); err != nil {\n\t\treturn \"\", fmt.Errorf(\"gemini stt: parse response: %w\", err)\n\t}","sourceCodeStart":255,"sourceCodeEnd":291,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/core/speech.go#L255-L291","documentation":"Thrown by GeminiSTT.Transcribe in core/speech.go when reading the Gemini API response body with io.ReadAll fails after a response was received. The connection was established but the body could not be fully read (connection reset mid-body, truncated chunked encoding, or context cancellation during read).","triggerScenarios":"io.ReadAll(resp.Body) errors: server closed the connection before sending the complete body, chunked transfer interrupted, proxy dropped the stream, or ctx was cancelled while reading.","commonSituations":"Flaky mobile/VPN networks dropping long responses; proxy/gateway with short read timeouts; Gemini service incident truncating responses.","solutions":["Simply retry the request — body-read interruptions are usually transient.","Check proxy/gateway timeouts if behind one.","Inspect the wrapped error: 'context canceled' means the caller gave up; adjust caller timeouts.","Check Google Cloud status for ongoing Gemini incidents."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"text, err := stt.Transcribe(ctx, audio)\nif err != nil {\n    if strings.Contains(err.Error(), \"read response\") {\n        // transient truncation: safe to retry once\n        text, err = stt.Transcribe(ctx, audio)\n    }\n    if err != nil { return err }\n}","preventionTips":["Retry read failures once — they are usually transient stream drops.","Avoid aggressive proxy idle/read timeouts for long API responses.","Use stable networks or retry logic for mobile/VPN users.","Monitor provider status pages for incidents causing truncated responses."],"tags":["network","io","speech-to-text","gemini"],"backgroundTag":"file-read-failed","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}