None of these are in the error message you'd hope for. Each one looked like my bug until I found the ffmpeg-shaped edge underneath.
1. overlay has no alpha= option
I wanted a layer to fade in over the background. The obvious guess — an alpha on the overlay filter — doesn't exist. overlay composites; it doesn't own the opacity of its input.
The fix is to fade the source before you overlay it, using fade with the alpha flag:
# WRONG: overlay has no alpha=
# [bg][fg]overlay=alpha=...
# RIGHT: fade the source's alpha, then overlay
[fg]format=yuva420p,fade=t=in:st=0:d=0.4:alpha=1[fgf];
[bg][fgf]overlayI lost an hour assuming a symmetry the filter graph doesn't have.
2. drawtext chokes on non-ASCII / spaced font paths
For multilingual captions I pointed drawtext at the CJK system fonts. It failed to render — the font paths have spaces and non-ASCII characters, and drawtext's fontfile= parsing can't handle them.
Fix: copy the font to a plain ASCII-named file and point drawtext at that copy.
cp "/System/.../Hiragino Sans W4.ttc" ./fonts/hiragino_w4.ttc
# then: drawtext=fontfile=./fonts/hiragino_w4.ttc:...After that, Japanese and Korean render cleanly instead of as tofu boxes.
3. The system ffmpeg was silently broken
Renders were failing in a way that pointed nowhere useful. The cause turned out to be a shared-library soname drift — the system's ffmpeg had been left linking against a library version that no longer matched. Nothing in my pipeline was wrong; the binary itself was.
4. On a recent Python, bet on a static ffmpeg
The reflex fix for #3 is "reinstall ffmpeg," but the usual static-build mirror was DNS-blocked on my network, and on a very recent Python (3.14) the media-related wheels don't always have prebuilt binaries — so pip would try to compile and fail. I sidestepped all of it by pulling a known-good static binary through the imageio-ffmpeg package, and pointing the pipeline at that.
import imageio_ffmpeg
FFMPEG = imageio_ffmpeg.get_ffmpeg_exe() # a pinned static binaryThe honest part
Three of these four looked like application bugs and were actually environment or filter-graph facts. The lesson I keep relearning with ffmpeg: when a render misbehaves, separate your graph from the binary and its inputs before you debug the graph. Pin a static binary, normalize font paths to ASCII, and read the filter docs for the specific option you're assuming exists — because half the time it doesn't.