Billionmail/BillionMail · error
create TTS request: %w
Error message
create TTS request: %w
What it means
BuildTTSRequest then calls http.NewRequest("POST", cfg.voiceBaseURL()+cartesiaTTSPath, ...); if the TTS endpoint URL cannot be parsed, NewRequest returns a *url.Error wrapped as 'create TTS request: %w'. The root cause is an invalid Cartesia base URL in VoiceConfig, not the transcript content.
Source
Thrown at core/internal/service/video_gen/voice.go:123
}
httpReq.Header.Set("X-API-Key", cfg.APIKey)
httpReq.Header.Set("Cartesia-Version", cartesiaAPIVersion)
httpReq.Header.Set("Content-Type", "application/json")
return httpReq, nil
}
// BuildTTSRequest constructs the HTTP request for text-to-speech.
// Exported for testing without making API calls.
func BuildTTSRequest(cfg VoiceConfig, req TTSRequest) (*http.Request, error) {
body, err := json.Marshal(req)
if err != nil {
return nil, fmt.Errorf("marshal TTS request: %w", err)
}
httpReq, err := http.NewRequest("POST", cfg.voiceBaseURL()+cartesiaTTSPath, bytes.NewReader(body))
if err != nil {
return nil, fmt.Errorf("create TTS request: %w", err)
}
httpReq.Header.Set("X-API-Key", cfg.APIKey)
httpReq.Header.Set("Cartesia-Version", cartesiaAPIVersion)
httpReq.Header.Set("Content-Type", "application/json")
return httpReq, nil
}
// CloneVoice creates a cloned voice from an audio sample URL via Cartesia API.
func CloneVoice(ctx context.Context, cfg VoiceConfig, name, audioURL string) (*VoiceCloneResponse, error) {
req := VoiceCloneRequest{
Name: name,
Description: fmt.Sprintf("Cloned voice for %s", name),
Mode: "url",
AudioURL: audioURL,
Language: "en",
}
View on GitHub (pinned to fc36c76c05)
Solutions
- Print and url.Parse cfg.voiceBaseURL()+cartesiaTTSPath to see the parse error
- Correct the Cartesia base URL (default https://api.cartesia.ai) in VoiceConfig or its environment variable, trimming whitespace
- Validate scheme and host at config-load time and fail fast with a clear message
- Reuse one validated base-URL helper for both clone and TTS paths so a fix covers both
Example fix
// before
httpReq, err := http.NewRequest("POST", cfg.voiceBaseURL()+cartesiaTTSPath, bytes.NewReader(body))
if err != nil {
return nil, fmt.Errorf("create TTS request: %w", err)
}
// after
u, uerr := url.Parse(cfg.voiceBaseURL() + cartesiaTTSPath)
if uerr != nil || u.Scheme == "" || u.Host == "" {
return nil, fmt.Errorf("invalid TTS endpoint URL %q: %w", cfg.voiceBaseURL()+cartesiaTTSPath, uerr)
}
httpReq, err := http.NewRequest("POST", u.String(), bytes.NewReader(body)) Defensive patterns
Strategy: try-catch
Validate before calling
func validateTTSEndpoint(cfg VoiceConfig) error {
u, err := url.Parse(cfg.voiceBaseURL() + cartesiaTTSPath)
if err != nil || u.Scheme == "" || u.Host == "" {
return fmt.Errorf("invalid TTS endpoint: %q", cfg.voiceBaseURL()+cartesiaTTSPath)
}
return nil
} Try / catch
httpReq, err := video_gen.BuildTTSRequest(cfg, req)
if err != nil {
var urlErr *url.Error
if errors.As(err, &urlErr) {
log.Errorf("bad TTS endpoint URL: %v", urlErr)
// fix VoiceConfig base URL before retrying
}
return err
} Prevention
- Validate the base URL once at startup and reuse it for all Cartesia calls
- Trim whitespace from config/env-derived URLs
- Pin the Cartesia base URL in deployment config rather than ad-hoc strings
- Cover the empty-base-URL case in TestBuildTTSRequest_Headers-style unit tests
When it happens
Trigger: http.NewRequest fails on cfg.voiceBaseURL()+cartesiaTTSPath: empty base URL, whitespace/control characters, or invalid scheme in the configured voice base URL.
Common situations: Unset or mis-typed TTS/API base URL env var; trailing newline from file-based config; scheme typos; hand-edited config pointing at an internal proxy with a bad URL.
Understand the failure class
Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.
Related errors
- create clone request: %w
- create lipsync request: %w
- cartesia TTS API error %d: %s
- create status request: %w
- marshal TTS request: %w
AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05).
Data as JSON: /api/errors/d0bafb16137d9bc1.
Report an issue: GitHub.