chenhg5/cc-connect · error
parse response: %w
Error message
parse response: %w
What it means
Thrown by QwenSTT.Transcribe in core/speech.go when the JSON response body from the Qwen ASR API cannot be unmarshaled into the expected {choices:[{message:{content}}]} structure. The underlying json.Unmarshal error is wrapped with 'parse response:'. Indicates the server replied with valid HTTP 200 but a body that is not the expected JSON shape (often HTML from a proxy or an error object).
Source
Thrown at core/speech.go:194
body, err := io.ReadAll(resp.Body)
if err != nil {
return "", fmt.Errorf("read response: %w", err)
}
if resp.StatusCode != http.StatusOK {
return "", fmt.Errorf("qwen asr API %d: %s", resp.StatusCode, string(body))
}
var result struct {
Choices []struct {
Message struct {
Content string `json:"content"`
} `json:"message"`
} `json:"choices"`
}
if err := json.Unmarshal(body, &result); err != nil {
return "", fmt.Errorf("parse response: %w", err)
}
if len(result.Choices) == 0 {
return "", fmt.Errorf("qwen asr: empty choices in response")
}
return strings.TrimSpace(result.Choices[0].Message.Content), nil
}
// GeminiSTT implements SpeechToText using the Google Gemini API.
// Audio is sent as inline_data (base64) in the contents array against the
// generateContent endpoint; the API key is sent via the x-goog-api-key header.
type GeminiSTT struct {
APIKey string
Model string
BaseURL string // internal; defaults to Google API, overridable for testing
Client *http.Client
}
View on GitHub (pinned to 4000b2338a)
Solutions
- Log/inspect the raw response body to see what was actually returned.
- Verify BaseURL uses the OpenAI-compatible endpoint (…/compatible-mode/v1) so the response has a 'choices' array.
- Check for proxies/gateways intercepting the request (corporate MITM, auth walls).
- Retry the request — truncated bodies are often transient network issues.
- If the model's schema changed, update the parsing struct in core/speech.go.
Defensive patterns
Strategy: try-catch
Try / catch
text, err := stt.Transcribe(ctx, audio)
if err != nil {
if strings.Contains(err.Error(), "parse response") {
slog.Warn("qwen asr: unexpected body, likely proxy/endpoint issue", "err", err)
return "", ErrUnexpectedResponse
}
return err
} Prevention
- Use the official OpenAI-compatible Qwen endpoint so responses always have 'choices'.
- Avoid proxies/gateways that can inject HTML error pages.
- Log raw bodies on parse failure to speed diagnosis.
- Keep the response struct in sync with the provider's documented schema.
When it happens
Trigger: json.Unmarshal fails on the 200-OK response body: body is HTML (auth portal/proxy page), truncated response, or a JSON object with different field names because BaseURL points at a non-OpenAI-compatible Qwen endpoint.
Common situations: Corporate proxy or gateway returning an HTML login page; BaseURL misconfigured so responses come from a different API shape; network middleware corrupting the body; Qwen changing response schema for a newer model.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
- gemini stt: parse response: %w
- parse JSON from %s: %w
- parse JSON from %s: %w
- marshal request: %w
- qwen asr API %d: %s
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/8cedc6f890fd509b.
Report an issue: GitHub.