chenhg5/cc-connect · error

gemini stt: read response: %w

Error message

gemini stt: read response: %w

What it means

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).

Source

Thrown at core/speech.go:273

	}

	apiURL := fmt.Sprintf("%s/models/%s:generateContent", g.BaseURL, url.PathEscape(g.Model))
	req, err := http.NewRequestWithContext(ctx, http.MethodPost, apiURL, bytes.NewReader(jsonData))
	if err != nil {
		return "", fmt.Errorf("gemini stt: create request: %w", err)
	}
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("x-goog-api-key", g.APIKey)

	resp, err := g.Client.Do(req)
	if err != nil {
		return "", fmt.Errorf("gemini stt: request: %w", err)
	}
	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return "", fmt.Errorf("gemini stt: read response: %w", err)
	}

	if resp.StatusCode != http.StatusOK {
		return "", fmt.Errorf("gemini stt API %d: %s", resp.StatusCode, string(body))
	}

	var result struct {
		Candidates []struct {
			Content struct {
				Parts []struct {
					Text string `json:"text"`
				} `json:"parts"`
			} `json:"content"`
		} `json:"candidates"`
	}
	if err := json.Unmarshal(body, &result); err != nil {
		return "", fmt.Errorf("gemini stt: parse response: %w", err)
	}

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Simply retry the request — body-read interruptions are usually transient.
  2. Check proxy/gateway timeouts if behind one.
  3. Inspect the wrapped error: 'context canceled' means the caller gave up; adjust caller timeouts.
  4. Check Google Cloud status for ongoing Gemini incidents.
Defensive patterns

Strategy: retry

Try / catch

text, err := stt.Transcribe(ctx, audio)
if err != nil {
    if strings.Contains(err.Error(), "read response") {
        // transient truncation: safe to retry once
        text, err = stt.Transcribe(ctx, audio)
    }
    if err != nil { return err }
}

Prevention

When it happens

Trigger: 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.

Common situations: Flaky mobile/VPN networks dropping long responses; proxy/gateway with short read timeouts; Gemini service incident truncating responses.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/49da8608ed99db03. Report an issue: GitHub.