chenhg5/cc-connect · error
qwen tts: read response: %w
Error message
qwen tts: read response: %w
What it means
After a successful HTTP exchange, Synthesize reads the entire response body with io.ReadAll. A read failure (connection reset mid-body, truncated chunked transfer, context cancelled during read) is wrapped as 'qwen tts: read response'. The status check happens only after this read succeeds.
Source
Thrown at core/tts.go:154
return nil, "", fmt.Errorf("qwen tts: marshal request: %w", err)
}
req, err := http.NewRequestWithContext(ctx, http.MethodPost, q.BaseURL, bytes.NewReader(jsonData))
if err != nil {
return nil, "", fmt.Errorf("qwen tts: create request: %w", err)
}
req.Header.Set("Authorization", "Bearer "+q.APIKey)
req.Header.Set("Content-Type", "application/json")
resp, err := q.Client.Do(req)
if err != nil {
return nil, "", fmt.Errorf("qwen tts: request: %w", err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, "", fmt.Errorf("qwen tts: read response: %w", err)
}
if resp.StatusCode != http.StatusOK {
return nil, "", fmt.Errorf("qwen tts API %d: %s", resp.StatusCode, body)
}
var result struct {
Code string `json:"code"`
Message string `json:"message"`
Output struct {
Audio struct {
URL string `json:"url"`
} `json:"audio"`
} `json:"output"`
}
if err := json.Unmarshal(body, &result); err != nil {
return nil, "", fmt.Errorf("qwen tts: parse response: %w", err)
}
if result.Code != "" {View on GitHub (pinned to 4000b2338a)
Solutions
- Retry the request — this is typically transient.
- Check the wrapped error: net errors like unexpected EOF/reset indicate network instability.
- Increase the caller's context deadline if large responses are expected.
- Check any LB/proxy idle timeouts between client and API.
Example fix
// before
body, err := io.ReadAll(resp.Body)
if err != nil { return nil, "", err } // give up
// after
body, err := io.ReadAll(resp.Body)
if err != nil {
if isRetryable(err) { return synthesizeWithRetry(ctx, text, opts) }
return nil, "", fmt.Errorf("qwen tts: read response: %w", err)
} Defensive patterns
Strategy: retry
Try / catch
audio, _, err := q.Synthesize(ctx, text, opts)
if err != nil && strings.Contains(err.Error(), "read response") {
if ne, ok := err.(net.Error); ok && ne.Timeout() {
return retryWithLongerDeadline(ctx, text, opts)
}
return fmt.Errorf("connection dropped during TTS response: %w", err)
} Prevention
- Always retry once on mid-body read failures; they are usually transient.
- Avoid very short context deadlines for large synthesis payloads.
- Check LB/proxy idle-timeout settings between client and API.
- Prefer stable networks for long-running agent sessions (warn on VPN/mobile).
When it happens
Trigger: io.ReadAll(resp.Body) returns an error: server closed connection mid-response, network interruption during body transfer, or ctx cancelled while streaming the body.
Common situations: Flaky mobile/VPN connection dropping mid-download; API gateway timing out and cutting the response; very slow network combined with a caller context deadline.
Related errors
- qwen tts: read audio: %w
- qwen tts: request: %w
- qwen tts: download audio: %w
- openai tts: read audio: %w
- read body from %s: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/838b7faf8d0355a7.
Report an issue: GitHub.