{"record":{"id":"9aeef3eb19dbffbf","repo":"babysor/MockingBird","slug":"ffmpeg-failed-join-cmd-n-proc-stderr","errorCode":null,"errorMessage":"ffmpeg failed: {' '.join(cmd)}\\n{proc.stderr}","messagePattern":"ffmpeg failed: (.+?)\\\\n(.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"skills/speak/scripts/render_timeline.py","lineNumber":118,"sourceCode":"    return v, v\n\n\ndef resolve_segment_cfg(index: int, config: Dict[str, Any]) -> Dict[str, Any]:\n    merged = dict(config.get(\"default\", {}))\n    for key, seg_cfg in config.get(\"segments\", {}).items():\n        lo, hi = parse_segment_key(key)\n        if lo <= index <= hi:\n            merged.update(seg_cfg)\n    return merged\n\n\n# ── ffmpeg helpers ────────────────────────────────────────────────────\n\n\ndef _run_ff(cmd: List[str]) -> None:\n    proc = subprocess.run(cmd, capture_output=True, text=True)\n    if proc.returncode != 0:\n        raise RuntimeError(f\"ffmpeg failed: {' '.join(cmd)}\\n{proc.stderr}\")\n\n\ndef ensure_ffmpeg() -> None:\n    if not shutil.which(\"ffmpeg\"):\n        raise RuntimeError(\"ffmpeg not found in PATH.\")\n\n\ndef probe_duration_ms(path: Path) -> float:\n    proc = subprocess.run(\n        [\n            \"ffprobe\", \"-v\", \"error\", \"-show_entries\", \"format=duration\",\n            \"-of\", \"default=noprint_wrappers=1:nokey=1\", str(path),\n        ],\n        capture_output=True, text=True,\n    )\n    if proc.returncode != 0:\n        raise RuntimeError(f\"ffprobe failed on {path}: {proc.stderr}\")\n    return float(proc.stdout.strip()) * 1000","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/babysor/MockingBird/blob/28dc5e14f12d7c754612af2fde8e78a4b03f8616/skills/speak/scripts/render_timeline.py#L100-L136","documentation":"RuntimeError raised by _run_ff whenever an ffmpeg subprocess exits non-zero; stderr is captured and included. All audio processing steps (pad/trim, atempo, delay, final mix) funnel through this helper.","triggerScenarios":"Any ffmpeg filter error: invalid adelay/amix/atempo arguments, unsupported/corrupt input file, missing encoder for the requested output format, or output path not writable.","commonSituations":"Old ffmpeg build lacking a filter or encoder, mistyped output extension (e.g. .m4a without an AAC encoder enabled), paths with characters that break arg assembly, or truncated TTS output files fed in.","solutions":["Read the embedded ffmpeg stderr — it names the exact failing filter/option","Reproduce the command manually in a shell to iterate quickly","Upgrade ffmpeg to a recent build if a filter/encoder is unsupported","Verify input audio files are valid and output dir is writable"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"import shutil\nassert shutil.which('ffmpeg'), 'ffmpeg required'","typeGuard":null,"tryCatchPattern":"try:\n    _run_ff(cmd)\nexcept RuntimeError as e:\n    print(e); subprocess.run(' '.join(cmd), shell=True)  # reproduce manually\n    raise","preventionTips":["Pin a recent ffmpeg version in Dockerfiles","Test the exact filter chain on samples first","Validate inputs are real audio files"],"tags":["ffmpeg","subprocess","audio","rendering"],"backgroundTag":"subprocess-nonzero-exit","analyzedSha":"28dc5e14f12d7c754612af2fde8e78a4b03f8616","analyzedAt":"2026-08-27T02:26:53.589Z","schemaVersion":2},"datasetVersion":"2026-08-27T03:17:27.898Z"}