{"record":{"id":"9a5cd341aade86d8","repo":"Billionmail/BillionMail","slug":"ffmpeg-compositing-failed-w-noutput-s","errorCode":null,"errorMessage":"ffmpeg compositing failed: %w\\noutput: %s","messagePattern":"ffmpeg compositing failed: %w\\\\noutput: (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/internal/service/video_gen/composite.go","lineNumber":196,"sourceCode":"}\n\n// CompositeVideo runs FFmpeg to combine screenshots + audio into a final video.\n// Requires: ffmpeg installed and in PATH.\nfunc CompositeVideo(ctx context.Context, cfg CompositeConfig) (*CompositeResult, error) {\n\targs := BuildFFmpegArgs(cfg)\n\tif args == nil {\n\t\treturn nil, fmt.Errorf(\"no scenes provided\")\n\t}\n\n\t// Ensure output directory exists\n\tif err := os.MkdirAll(filepath.Dir(cfg.OutputPath), 0755); err != nil {\n\t\treturn nil, fmt.Errorf(\"create output dir: %w\", err)\n\t}\n\n\tcmd := exec.CommandContext(ctx, \"ffmpeg\", args...)\n\tout, err := cmd.CombinedOutput()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"ffmpeg compositing failed: %w\\noutput: %s\", err, string(out))\n\t}\n\n\t// Calculate total duration from scenes\n\tvar totalDuration time.Duration\n\tfor _, scene := range cfg.Scenes {\n\t\ttotalDuration += scene.Duration\n\t}\n\n\treturn &CompositeResult{\n\t\tVideoPath: cfg.OutputPath,\n\t\tDuration:  totalDuration,\n\t}, nil\n}\n\n// SceneFromScreenshot creates a Scene from a screenshot path and audio path.\nfunc SceneFromScreenshot(imagePath, audioPath string, duration time.Duration) Scene {\n\treturn Scene{\n\t\tImagePath: imagePath,","sourceCodeStart":178,"sourceCodeEnd":214,"githubUrl":"https://github.com/Billionmail/BillionMail/blob/fc36c76c050c3775c5e899faf7403cf0262d2744/core/internal/service/video_gen/composite.go#L178-L214","documentation":"CompositeVideo runs `ffmpeg` with the built arguments and captures combined stdout/stderr. If ffmpeg exits non-zero, the error is wrapped as 'ffmpeg compositing failed' plus ffmpeg's full output, which contains the actual diagnostic. It is the generic pass-through for any ffmpeg execution failure.","triggerScenarios":"exec.CommandContext(ctx, \"ffmpeg\", args...).CombinedOutput() returns err — ffmpeg not installed/on PATH, invalid codec or filter args, missing input files, unsupported pixel format, context cancelled mid-encode, or out-of-memory/disk-full during encode.","commonSituations":"ffmpeg missing from the container image; wrong audio/video codec names in BuildFFmpegArgs; scene image paths that don't exist; context timeout shorter than the encode; ffmpeg version differences (codec name changed) between dev and prod.","solutions":["Read the `output:` section of the error — ffmpeg prints the precise failing option/input there","Ensure ffmpeg is installed and on PATH in the runtime environment","Verify every scene's screenshot and audio file exists and matches the args (paths, durations)","Run the exact failing ffmpeg command manually to reproduce and iterate on args","If 'signal: killed'/context error, increase the timeout or reduce encode resolution/settings"],"exampleFix":"// before (Dockerfile)\nRUN apt-get update && apt-get install -y imagemagick\n// after\nRUN apt-get update && apt-get install -y imagemagick ffmpeg","handlingStrategy":"try-catch","validationCode":"if _, err := exec.LookPath(\"ffmpeg\"); err != nil {\n    return fmt.Errorf(\"ffmpeg required but not on PATH: %w\", err)\n}\nfor _, s := range cfg.Scenes {\n    if _, err := os.Stat(s.ImagePath); err != nil { return err }\n    if _, err := os.Stat(s.AudioPath); err != nil { return err }\n}","typeGuard":null,"tryCatchPattern":"res, err := video_gen.CompositeVideo(ctx, cfg)\nif err != nil {\n    var ee *exec.ExitError\n    if errors.As(err, &ee) {\n        // err's text includes ffmpeg's combined output — surface it for debugging\n        log.Printf(\"ffmpeg exit %d. output: %s\", ee.ExitCode(), extractOutput(err))\n    }\n    return err\n}","preventionTips":["Install ffmpeg in every runtime image running video_gen","Read the `output:` section of the error first — it names the failing option/input","Pin an ffmpeg version and test BuildFFmpegArgs output against it (codec names vary by version)","Set encode timeouts above worst-case scene total duration"],"tags":["ffmpeg","exec","video-encoding","external-command"],"backgroundTag":"external-command-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"}