{"record":{"id":"6157ea6fa4457af6","repo":"chenhg5/cc-connect","slug":"qwen-tts-download-audio-w","errorCode":null,"errorMessage":"qwen tts: download audio: %w","messagePattern":"qwen tts: download audio: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/tts.go","lineNumber":186,"sourceCode":"\t}\n\tif err := json.Unmarshal(body, &result); err != nil {\n\t\treturn nil, \"\", fmt.Errorf(\"qwen tts: parse response: %w\", err)\n\t}\n\tif result.Code != \"\" {\n\t\treturn nil, \"\", fmt.Errorf(\"qwen tts API error %s: %s\", result.Code, result.Message)\n\t}\n\tif result.Output.Audio.URL == \"\" {\n\t\treturn nil, \"\", fmt.Errorf(\"qwen tts: empty audio URL in response\")\n\t}\n\n\t// Download WAV from temporary URL\n\taudioReq, err := http.NewRequestWithContext(ctx, http.MethodGet, result.Output.Audio.URL, nil)\n\tif err != nil {\n\t\treturn nil, \"\", fmt.Errorf(\"qwen tts: create download request: %w\", err)\n\t}\n\taudioResp, err := q.Client.Do(audioReq)\n\tif err != nil {\n\t\treturn nil, \"\", fmt.Errorf(\"qwen tts: download audio: %w\", err)\n\t}\n\tdefer audioResp.Body.Close()\n\n\twavData, err := io.ReadAll(audioResp.Body)\n\tif err != nil {\n\t\treturn nil, \"\", fmt.Errorf(\"qwen tts: read audio: %w\", err)\n\t}\n\treturn wavData, \"wav\", nil\n}\n\n// ──────────────────────────────────────────────────────────────\n// OpenAITTS — OpenAI-compatible TTS implementation (P1)\n// ──────────────────────────────────────────────────────────────\n\n// OpenAITTS implements TextToSpeech using the OpenAI /v1/audio/speech API.\ntype OpenAITTS struct {\n\tAPIKey  string\n\tBaseURL string","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/core/tts.go#L168-L204","documentation":"QwenTTS.Synthesize downloads the synthesized WAV from the temporary URL returned by DashScope (core/tts.go:186) using the shared q.Client. This error wraps a Client.Do failure: the GET request to the audio URL could not be completed at the transport level.","triggerScenarios":"Network failure, DNS resolution failure for the audio host, TLS handshake error, the temporary URL already expired and the connection was reset, or the 60s client timeout elapsing before the download starts.","commonSituations":"Synthesis succeeded but the download ran from a network without internet egress (e.g. server-side code in a restricted VPC), DashScope's temporary CDN URL expired because of a delay between generation and download, or a proxy/firewall blocks the audio host (aliyuncs OSS domains).","solutions":["Check network egress/DNS from the machine running the code to the audio host domain","Retry Synthesize — temporary URLs are short-lived, so download immediately after generation","Increase the http.Client timeout in NewQwenTTS for long/large audio downloads","Verify proxy/firewall rules allow HTTPS to DashScope audio/CDN domains"],"exampleFix":"// before\nclient = &http.Client{Timeout: 60 * time.Second}\n// after\nclient = &http.Client{Timeout: 120 * time.Second} // tolerate slow CDN downloads","handlingStrategy":"retry","validationCode":"// Pre-check egress reachability at startup:\nreq, _ := http.NewRequest(http.MethodHead, strings.TrimRight(tts.BaseURL, \"/\"), nil)\nif _, err := http.DefaultClient.Do(req); err != nil {\n    log.Printf(\"warning: no network egress to TTS provider host: %v\", err)\n}","typeGuard":null,"tryCatchPattern":"var audio []byte\nvar format string\nvar err error\nfor i := 0; i < 3; i++ {\n    audio, format, err = tts.Synthesize(ctx, text, opts)\n    if err == nil || !strings.Contains(err.Error(), \"download audio\") { break }\n    time.Sleep(time.Duration(1<<i) * time.Second) // exponential backoff\n}\nif err != nil { return err }","preventionTips":["Download the temporary URL immediately after generation — it expires quickly","Ensure firewall/proxy rules allow HTTPS to DashScope audio/CDN domains","Use a generous client timeout (60s+) for the download client"],"tags":["tts","network","http","download","qwen"],"backgroundTag":"network-request-failed","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}