Billionmail/BillionMail · error
lip sync timed out after %v
Error message
lip sync timed out after %v
What it means
pollLipSync polls the external lip-sync provider until the job completes, but stops after lipSyncTimeout has elapsed. If the provider still has not finished by the deadline, the poll loop aborts with this error.
Source
Thrown at core/internal/service/video_gen/orchestrator.go:404
if err != nil {
return "", fmt.Errorf("voice clone: %w", err)
}
return resp.ID, nil
}
if defaultID != "" {
return defaultID, nil
}
return "", fmt.Errorf("no voice configured: set VOICE_SAMPLE_URL or VOICE_DEFAULT_ID")
}
// pollLipSync polls lip sync status until completed or timeout.
func pollLipSync(ctx context.Context, cfg LipSyncConfig, jobID string) (string, error) {
deadline := time.Now().Add(lipSyncTimeout)
for {
if time.Now().After(deadline) {
return "", fmt.Errorf("lip sync timed out after %v", lipSyncTimeout)
}
resp, err := CheckLipSyncStatus(ctx, cfg, jobID)
if err != nil {
return "", fmt.Errorf("check lip sync status: %w", err)
}
switch resp.Status {
case "completed":
if resp.VideoURL == "" {
return "", fmt.Errorf("lip sync completed but no video URL")
}
return resp.VideoURL, nil
case "failed":
return "", fmt.Errorf("lip sync failed: %s", resp.Error)
}
time.Sleep(lipSyncPollDelay)View on GitHub (pinned to fc36c76c05)
Solutions
- Retry RunPipeline's lip-sync stage; transient provider backlogs usually resolve
- Increase lipSyncTimeout to a value appropriate for the video length
- Verify the job ID is valid and the lip-sync submission succeeded (check upstream logs)
- Check provider status/dashboard for ongoing incidents
Example fix
// before const lipSyncTimeout = 10 * time.Minute // after const lipSyncTimeout = 30 * time.Minute // long videos need more headroom
Defensive patterns
Strategy: retry
Validate before calling
if lipSyncTimeout < estimatedProcessingTime(videoDurationSec) {
return fmt.Errorf("lipSyncTimeout %v too short for %ds video", lipSyncTimeout, videoDurationSec)
} Try / catch
url, err := pollLipSync(ctx, cfg, jobID)
if err != nil && strings.Contains(err.Error(), "timed out") {
// check the job once more directly — it may have completed after the deadline
return CheckLipSyncStatus(ctx, cfg, jobID)
} Prevention
- Size lipSyncTimeout relative to input media duration
- Alert on repeated timeouts — they usually indicate provider degradation
- Make the timeout configurable via env so it can be tuned without a redeploy
- Poll less frequently with backoff to avoid provider throttling
When it happens
Trigger: CheckLipSyncStatus keeps returning a non-terminal status (processing/queued) past lipSyncTimeout while RunPipeline waits; typically for long videos, provider congestion, or a stuck job.
Common situations: Provider outage or degraded service; very long source audio; job ID whose upstream request silently failed so it never completes; timeout too short for large inputs.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- rate limiter: %w
- lipsync API call: %w
- voice clone: %w
- check lip sync status: %w
- lip sync completed but no video URL
AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05).
Data as JSON: /api/errors/8b3f824b825328fa.
Report an issue: GitHub.