chenhg5/cc-connect · error

qwen tts: create download request: %w

Error message

qwen tts: create download request: %w

What it means

After QwenTTS.Synthesize obtains a temporary audio URL from DashScope (core/tts.go:182), it builds a GET request with http.NewRequestWithContext to download the WAV file. This error wraps any failure of http.NewRequestWithContext itself — almost always a malformed or unparseable URL string returned by the API.

Source

Thrown at core/tts.go:182

			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", nil
}

// ──────────────────────────────────────────────────────────────
// OpenAITTS — OpenAI-compatible TTS implementation (P1)
// ──────────────────────────────────────────────────────────────

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Log result.Output.Audio.URL when this error occurs and validate it is a well-formed absolute http/https URL
  2. Use net/url.Parse on the URL before creating the request to fail with a clearer message
  3. Re-run synthesis to get a fresh temporary URL — if the API persistently returns invalid URLs, report/check the provider
  4. Ensure no custom proxy layer is rewriting the audio URL into a non-absolute form

Example fix

// before
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)
}
// after
u, perr := url.Parse(result.Output.Audio.URL)
if perr != nil || (u.Scheme != "http" && u.Scheme != "https") {
    return nil, "", fmt.Errorf("qwen tts: invalid audio URL %q: %w", result.Output.Audio.URL, perr)
}
audioReq, err := http.NewRequestWithContext(ctx, http.MethodGet, u.String(), nil)
if err != nil {
    return nil, "", fmt.Errorf("qwen tts: create download request: %w", err)
}
Defensive patterns

Strategy: validation

Validate before calling

u, err := url.Parse(audioURL)
if err != nil || (u.Scheme != "http" && u.Scheme != "https") || u.Host == "" {
    // don't build a request; reject before http.NewRequestWithContext
    return fmt.Errorf("invalid audio URL: %q", audioURL)
}

Type guard

func isValidAbsURL(s string) bool {
    u, err := url.Parse(s)
    return err == nil && (u.Scheme == "http" || u.Scheme == "https") && u.Host != ""
}

Try / catch

audio, format, err := tts.Synthesize(ctx, text, opts)
if err != nil && strings.Contains(err.Error(), "create download request") {
    return fmt.Errorf("tts provider returned unusable audio URL: %w", err)
}

Prevention

When it happens

Trigger: The URL string in result.Output.Audio.URL is not a valid absolute HTTP URL (e.g. empty scheme, malformed characters, control characters, or the API returned a relative/garbage value) so net/http cannot construct the request.

Common situations: A misbehaving or mocked DashScope endpoint returning an invalid URL, URL encoding issues when the temporary URL contains characters that need escaping, or a custom/proxied BaseURL altering what the API returns as the audio location.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


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