Billionmail/BillionMail · error
lipsync API call: %w
Error message
lipsync API call: %w
What it means
SubmitLipSync wraps errors from cfg.doHTTP(httpReq) — i.e. the request could not be completed at the transport level: DNS resolution failure, connection refused/TLS handshake error, timeout, or context cancellation. It is distinct from [453], which fires when the server responds with a non-2xx status; here there is no usable HTTP response at all.
Source
Thrown at core/internal/service/video_gen/lipsync.go:119
}
// SubmitLipSync submits a lip sync job and returns the job ID.
func SubmitLipSync(ctx context.Context, cfg LipSyncConfig, audioURL, videoURL string) (string, error) {
req := LipSyncRequest{
AudioURL: audioURL,
VideoURL: videoURL,
SynergizeAudio: true,
}
httpReq, err := BuildLipSyncRequest(cfg, req)
if err != nil {
return "", err
}
httpReq = httpReq.WithContext(ctx)
resp, err := cfg.doHTTP(httpReq)
if err != nil {
return "", fmt.Errorf("lipsync API call: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated {
body, _ := io.ReadAll(resp.Body)
return "", fmt.Errorf("lipsync API error %d: %s", resp.StatusCode, string(body))
}
var result LipSyncResponse
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return "", fmt.Errorf("decode lipsync response: %w", err)
}
return result.ID, nil
}
// CheckLipSyncStatus checks the status of a lip sync job.
func CheckLipSyncStatus(ctx context.Context, cfg LipSyncConfig, jobID string) (*LipSyncResponse, error) {
httpReq, err := BuildLipSyncStatusRequest(cfg, jobID)View on GitHub (pinned to fc36c76c05)
Solutions
- Verify network connectivity/DNS to the lipsync base URL host (curl the base URL from the same machine)
- Check ctx deadlines and cancelations — pass a context with an adequate timeout for media upload
- Confirm TLS is valid (system CA bundle present in container images; correct scheme http vs https)
- Inspect and unwrap the wrapped error with errors.Is(err, context.DeadlineExceeded)/net.Error to classify, then retry transient kinds with backoff
Example fix
// before
id, err := SubmitLipSync(ctx, cfg, ...) // bare ctx may be canceled too early
// after
ctx, cancel := context.WithTimeout(ctx, 60*time.Second)
defer cancel()
id, err := SubmitLipSync(ctx, cfg, ...)
if err != nil {
if errors.Is(err, context.DeadlineExceeded) { /* retry with backoff */ }
} Defensive patterns
Strategy: retry
Validate before calling
// before calling: cheap reachability preflight
ctx, cancel := context.WithTimeout(ctx, 60*time.Second)
defer cancel()
if err := ctx.Err(); err != nil {
return fmt.Errorf("context already done: %w", err)
} Type guard
func isTransientNetErr(err error) bool {
var ne net.Error
if errors.As(err, &ne) && ne.Timeout() { return true }
return errors.Is(err, context.DeadlineExceeded) ||
errors.Is(err, syscall.ECONNREFUSED) ||
errors.Is(err, syscall.ECONNRESET)
} Try / catch
id, err := SubmitLipSync(ctx, cfg, ...)
if err != nil {
if isTransientNetErr(err) {
// retry with exponential backoff, honoring ctx
}
if errors.Is(err, context.Canceled) {
// caller canceled; do not retry
}
return fmt.Errorf("submit failed: %w", err)
} Prevention
- Always pass a context with an explicit timeout sized for media uploads
- Configure retries with exponential backoff for idempotent status checks; cap submit retries
- Verify egress/firewall rules allow outbound HTTPS to the provider in each environment
- Monitor DNS/connectivity to the provider endpoint in health checks
When it happens
Trigger: Calling SubmitLipSync when the lipsync provider host is unreachable (DNS failure, wrong host/port), the network is down, TLS certs are invalid/expired, cfg.doHTTP has no/rejecting timeout, or the caller's ctx is canceled before the response arrives.
Common situations: Provider outage or regional block; container without outbound internet/Egress rules blocking the API; proxy required but not configured; 5-second default timeout exceeded on slow uploads; test environment pointing at a non-existent host.
Related errors
- lipsync status API call: %w
- download lipsync video: %w
- cartesia clone API call: %w
- cartesia TTS API call: %w
- base URL not configured
AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05).
Data as JSON: /api/errors/135bb1598636b4a3.
Report an issue: GitHub.