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

  1. Log/inspect the raw response body to see what was actually returned.
  2. Verify BaseURL uses the OpenAI-compatible endpoint (…/compatible-mode/v1) so the response has a 'choices' array.
  3. Check for proxies/gateways intercepting the request (corporate MITM, auth walls).
  4. Retry the request — truncated bodies are often transient network issues.
  5. 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

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


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