chenhg5/cc-connect · error
qwen tts: empty audio URL in response
Error message
qwen tts: empty audio URL in response
What it means
QwenTTS.Synthesize (core/tts.go:176) calls the Alibaba DashScope multimodal-generation API, parses the JSON body, and requires output.audio.url to contain a temporary URL from which the WAV file can be downloaded. This error is thrown when the API returned HTTP 200 with a parsable body and no business error code, yet the audio URL field is empty — i.e. the response shape did not carry the expected result.
Source
Thrown at core/tts.go:176
}
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 != "" {
return nil, "", fmt.Errorf("qwen tts API error %s: %s", result.Code, result.Message)
}
if result.Output.Audio.URL == "" {
return nil, "", fmt.Errorf("qwen tts: empty audio URL in response")
}
// Download WAV from temporary URL
audioReq, err := http.NewRequestWithContext(ctx, http.MethodGet, result.Output.Audio.URL, nil)
if err != nil {
return nil, "", fmt.Errorf("qwen tts: create download request: %w", err)
}
audioResp, err := q.Client.Do(audioReq)
if err != nil {
return nil, "", fmt.Errorf("qwen tts: download audio: %w", err)
}
defer audioResp.Body.Close()
wavData, err := io.ReadAll(audioResp.Body)
if err != nil {
return nil, "", fmt.Errorf("qwen tts: read audio: %w", err)
}
return wavData, "wav", nilView on GitHub (pinned to 4000b2338a)
Solutions
- Verify the configured model is a DashScope TTS model (default qwen3-tts-flash) that returns output.audio.url for this endpoint
- Log the raw response body on this error to inspect what output.audio actually contained
- Check BaseURL points at the multimodal-generation endpoint, not another DashScope service
- Update the client if DashScope changed the response schema; if the API now returns base64 audio, adapt parsing to that shape
Example fix
// before
if result.Output.Audio.URL == "" {
return nil, "", fmt.Errorf("qwen tts: empty audio URL in response")
}
// after
if result.Output.Audio.URL == "" {
return nil, "", fmt.Errorf("qwen tts: empty audio URL in response: body=%s", string(body))
} Defensive patterns
Strategy: try-catch
Validate before calling
// No pre-call validation possible; verify provider/model config at startup:
if ttsCfg.Provider == "qwen" && !strings.HasPrefix(ttsCfg.Model, "qwen") && ttsCfg.Model != "" {
log.Printf("warning: model %q may not return an audio URL from the DashScope multimodal endpoint", ttsCfg.Model)
} Type guard
func hasAudioURL(body []byte) bool {
var r struct { Output struct { Audio struct { URL string `json:"url"` } `json:"audio"` } `json:"output"` }
if err := json.Unmarshal(body, &r); err != nil { return false }
return r.Output.Audio.URL != ""
} Try / catch
audio, format, err := tts.Synthesize(ctx, text, opts)
if err != nil {
if strings.Contains(err.Error(), "empty audio URL") {
// fall back to a secondary TTS provider or notify user
return fallbackSynthesize(ctx, text)
}
return err
} Prevention
- Pin the model to a qwen-tts family model that returns audio URLs
- Log raw API responses at debug level so schema drift is visible immediately
- Pin/verify BaseURL against the official DashScope multimodal-generation endpoint
When it happens
Trigger: DashScope returns 200 with a JSON body whose output.audio.url is missing or empty: e.g. the configured model does not return audio URLs (wrong model name for this endpoint), the API changed its response schema, a partial success was returned, or a proxy/gateway answered 200 with a non-TTS JSON body.
Common situations: Configuring QwenTTS with a model other than a qwen-tts family model (e.g. a text-only qwen model), pointing BaseURL at a compatible-but-different endpoint that returns audio inline as base64 instead of a URL, or DashScope API schema drift.
Understand the failure class
Background: "empty response", "returned no data", "empty embeddings": what HTTP 200-with-empty-body errors mean across libraries — this error's family across 36 libraries.
Related errors
- qwen tts: create download request: %w
- qwen tts: create request: %w
- qwen tts: request: %w
- qwen tts API %d: %s
- qwen tts: download audio: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/b08fe9b8d08b1bce.
Report an issue: GitHub.