{"record":{"id":"86ec6116e735a5b3","repo":"Billionmail/BillionMail","slug":"lip-sync-failed-s","errorCode":null,"errorMessage":"lip sync failed: %s","messagePattern":"lip sync failed: (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/internal/service/video_gen/orchestrator.go","lineNumber":419,"sourceCode":"\tdeadline := time.Now().Add(lipSyncTimeout)\n\tfor {\n\t\tif time.Now().After(deadline) {\n\t\t\treturn \"\", fmt.Errorf(\"lip sync timed out after %v\", lipSyncTimeout)\n\t\t}\n\n\t\tresp, err := CheckLipSyncStatus(ctx, cfg, jobID)\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"check lip sync status: %w\", err)\n\t\t}\n\n\t\tswitch resp.Status {\n\t\tcase \"completed\":\n\t\t\tif resp.VideoURL == \"\" {\n\t\t\t\treturn \"\", fmt.Errorf(\"lip sync completed but no video URL\")\n\t\t\t}\n\t\t\treturn resp.VideoURL, nil\n\t\tcase \"failed\":\n\t\t\treturn \"\", fmt.Errorf(\"lip sync failed: %s\", resp.Error)\n\t\t}\n\n\t\ttime.Sleep(lipSyncPollDelay)\n\t}\n}\n\n// withRetry retries a function up to maxRetries times with exponential backoff.\nfunc withRetry[T any](fn func() (T, error)) (T, error) {\n\tvar result T\n\tvar err error\n\tdelay := retryBaseDelay\n\n\tfor attempt := 0; attempt <= maxRetries; attempt++ {\n\t\tresult, err = fn()\n\t\tif err == nil {\n\t\t\treturn result, nil\n\t\t}\n\t\tif attempt < maxRetries {","sourceCodeStart":401,"sourceCodeEnd":437,"githubUrl":"https://github.com/Billionmail/BillionMail/blob/fc36c76c050c3775c5e899faf7403cf0262d2744/core/internal/service/video_gen/orchestrator.go#L401-L437","documentation":"The lip-sync provider explicitly reported the job as 'failed'. pollLipSync wraps the provider-supplied error message (resp.Error) in this error and surfaces it to RunPipeline. The real cause is inside the %s payload.","triggerScenarios":"CheckLipSyncStatus returns Status==\"failed\"; the provider rejected or crashed the job (bad audio/video input, unsupported format, content policy rejection, provider-side error).","commonSituations":"Input video/audio too short or too long for the model; corrupted screenshot/footage file; voices whose sample URL expired; provider capacity errors reported as job failure.","solutions":["Inspect the %s message for the provider's specific failure reason","Re-encode/validate the input media (duration, codec, resolution) before submitting","Re-submit the job — some failures are transient provider errors","Test with a known-good small input to isolate whether the input or the provider is at fault"],"exampleFix":"// before\njobID, err := SubmitLipSync(ctx, cfg, videoURL, voiceID)\n// after\nif err := validateLipSyncInput(videoURL, voiceID); err != nil {\n\treturn fmt.Errorf(\"invalid lip sync input: %w\", err)\n}\njobID, err := SubmitLipSync(ctx, cfg, videoURL, voiceID)","handlingStrategy":"retry","validationCode":"if videoDurationSec < minSupportedSec || videoDurationSec > maxSupportedSec {\n\treturn fmt.Errorf(\"video duration %ds outside supported range\", videoDurationSec)\n}\nif voiceID == \"\" {\n\treturn fmt.Errorf(\"voice ID required before lip sync\")\n}","typeGuard":"func isRetryableLipSyncFailure(providerErrMsg string) bool {\n\tmsg := strings.ToLower(providerErrMsg)\n\treturn strings.Contains(msg, \"capacity\") || strings.Contains(msg, \"internal\") || strings.Contains(msg, \"timeout\")\n}","tryCatchPattern":"url, err := pollLipSync(ctx, cfg, jobID)\nvar lipErr *LipSyncFailedError\nif errors.As(err, &lipErr) && isRetryableLipSyncFailure(lipErr.ProviderMessage) {\n\treturn resubmitLipSync(ctx, cfg)\n}","preventionTips":["Validate input media duration/codec/format before submitting jobs","Ensure voice samples resolve to live URLs at submission time","Classify provider error messages: retry transient ones, surface input errors to users","Keep a known-good sample input for end-to-end provider health checks"],"tags":["external-service","job-failure","media-processing","lip-sync"],"backgroundTag":"upstream-job-failed","analyzedSha":"fc36c76c050c3775c5e899faf7403cf0262d2744","analyzedAt":"2026-09-05T21:28:54.019Z","contentChangedAt":"2026-09-05T21:28:54.019Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}