langchain-ai/deepagents · error · VideoExtractionError

Video payload contains no video stream

Error message

Video payload contains no video stream

What it means

The container opened successfully but contains no stream of type 'video' (only audio, subtitles, data, or nothing). `_find_video_stream` raises `VideoExtractionError` because frame extraction is impossible without a video stream.

Source

Thrown at libs/deepagents/deepagents/middleware/_video.py:250

    errors: list[type[BaseException]] = [OSError]
    av_error = getattr(av, "error", None)
    for name in ("FFmpegError", "InvalidDataError"):
        error_type = getattr(av_error, name, None)
        if (
            isinstance(error_type, type)
            and issubclass(error_type, BaseException)
            and not any(issubclass(error_type, existing) for existing in errors)
        ):
            errors.append(error_type)
    return tuple(errors)


def _find_video_stream(container: Any) -> Any:  # noqa: ANN401  # PyAV types are unavailable without the [video] extra
    """Return the first video stream in `container` or raise."""
    video_stream = next((s for s in container.streams if s.type == "video"), None)
    if video_stream is None:
        msg = "Video payload contains no video stream"
        raise VideoExtractionError(msg)
    return video_stream


def _stream_start_pts(video_stream: Any) -> int:  # noqa: ANN401  # PyAV types are unavailable without the [video] extra
    """Return the stream start timestamp in stream time-base units."""
    start_time = getattr(video_stream, "start_time", None)
    return int(start_time) if start_time is not None else 0


def _stream_start_seconds(video_stream: Any, time_base: float) -> float:  # noqa: ANN401  # PyAV types are unavailable without the [video] extra
    """Return the stream start timestamp in seconds."""
    return _stream_start_pts(video_stream) * time_base


def _frame_seconds(frame: Any, *, time_base: float, stream_start_seconds: float) -> float | None:  # noqa: ANN401  # PyAV types are unavailable without the [video] extra
    """Return a frame timestamp normalized to seconds from the video start."""
    pts = getattr(frame, "pts", None)
    if pts is not None:

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Confirm the file actually contains a video track (ffprobe should list a video stream)
  2. Point the extraction at the correct file if an audio file was passed by mistake
  3. Catch `VideoExtractionError` and route audio-only files to an audio pipeline
  4. Re-transcode with `ffmpeg -c:v ...` if the source lost its video stream

Example fix

// before
frames = extract_video_frames(audio_bytes, offset_seconds=0, duration_seconds=5, sampling_rate=1)
// after
probe = subprocess.run(["ffprobe", "-v", "error", "-select_streams", "v", "-show_entries", "stream=index", "-of", "csv", path])
if probe.stdout.strip():
    frames = extract_video_frames(video_bytes, offset_seconds=0, duration_seconds=5, sampling_rate=1)
Defensive patterns

Strategy: try-catch

Validate before calling

has_video = subprocess.run(
    ["ffprobe", "-v", "error", "-select_streams", "v:0", "-show_entries", "stream=codec_type", "-of", "csv", path],
    capture_output=True, text=True,
).stdout.strip() != ""

Try / catch

try:
    result = extract_video_frames(content, offset_seconds=0, duration_seconds=10, sampling_rate=1)
except VideoExtractionError as exc:
    if "no video stream" in str(exc):
        route_to_audio_pipeline(content)
    result = None

Prevention

When it happens

Trigger: Passing an audio-only file (mp3, m4a, wav), a data-only container, or an empty/headers-only file that FFmpeg still manages to open.

Common situations: Mixing up audio and video uploads; a .mp4 that is actually an audio track; stripped video streams after transcoding.

Related errors


AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29). Data as JSON: /api/errors/4833a180d18eb543. Report an issue: GitHub.