unslothai/unsloth · error · RuntimeError

WebM export failed (libvpx-vp9 unavailable?): {exc}

Error message

WebM export failed (libvpx-vp9 unavailable?): {exc}

What it means

The catch-all at the bottom of _transcode_webm: any non-RuntimeError exception during open/decode/encode is re-wrapped as 'WebM export failed (libvpx-vp9 unavailable?)' with the original exception chained. The leading hypothesis in the message is the common one — the PyAV build lacks the libvpx-vp9 encoder — but the wrapped exc is the real diagnosis. Deliberate RuntimeErrors (no video stream) are re-raised untouched.

Source

Thrown at studio/backend/core/inference/video_gallery.py:202

                        for out_packet in out_v.encode(frame.reformat(format = "yuv420p")):
                            dst.mux(out_packet)
                    continue
                for frame in packet.decode():
                    for resampled in resampler.resample(frame):
                        # Let the FIFO time the output: the resampler's frames do not line up with Opus' fixed frame size.
                        resampled.pts = None
                        fifo.write(resampled)
                    _drain_audio()
            for packet in out_v.encode():
                dst.mux(packet)
            if out_a is not None:
                _drain_audio(flush = True)
                for packet in out_a.encode():
                    dst.mux(packet)
    except RuntimeError:
        raise
    except Exception as exc:  # noqa: BLE001 -- surface as "encoder unavailable"
        raise RuntimeError(f"WebM export failed (libvpx-vp9 unavailable?): {exc}") from exc


# Ceilings for a GIF export, which must hold every kept frame in memory before encoding. 720 px and 300 frames (25s at the
# 12 fps target) bound that at roughly 150 MB for the widest clip a generate request allows.
_GIF_MAX_EDGE = 720
_GIF_MAX_FRAMES = 300


def _transcode_gif(path: Path) -> bytes:
    import io

    try:
        import av
        from PIL import Image
    except Exception as exc:  # noqa: BLE001 -- missing deps -> no transcode
        raise RuntimeError("GIF export needs the 'av' and 'Pillow' packages.") from exc
    frames: list[Any] = []
    try:

View on GitHub (pinned to 203007d190)

Solutions

  1. Read the chained original exception ({exc}) — it names the actual failing operation/codec.
  2. If it is indeed libvpx-vp9: pip install --force-reinstall av to get the PyPI wheel whose ffmpeg includes libvpx.
  3. Check the source clip plays with ffprobe/ffplay; a decode-side error is a corrupt input, not a codec issue.
  4. Fall back to MP4 export (H.264, different encoder) while the environment is fixed.

Example fix

# before: distro av package without libvpx -> RuntimeError('libvpx-vp9 unavailable?')
sudo apt remove python3-av

# after: PyPI wheel bundles ffmpeg with libvpx-vp9
pip install --force-reinstall av
Defensive patterns

Strategy: fallback

Validate before calling

import av

def vp9_encoder_available() -> bool:
    try:
        with av.open("out.webm", "w", format="webm") as c:
            c.add_stream("libvpx-vp9", rate=24)
        return True
    except Exception:
        return False

Try / catch

try:
    _transcode_webm(src, dest)
except RuntimeError as e:
    if "libvpx-vp9 unavailable" in str(e):
        data = export_clip(clip, fmt="mp4")  # different encoder, same clip
    else:
        raise

Prevention

When it happens

Trigger: PyAV installed from source or a distro package compiled without libvpx; a decode error mid-clip (corrupt frame); muxing failures such as unmatched stream parameters; audio path failures (Opus encoder missing) also land here.

Common situations: Distro Python-av packages (Debian/Ubuntu apt builds sometimes exclude libvpx); old PyAV versions predating bundled ffmpeg with VP9; partially corrupt generated clips.

Related errors


AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15). Data as JSON: /api/errors/0d2c990305c607e2. Report an issue: GitHub.