Comfy-Org/ComfyUI · error · ValueError

No video stream found in file '{self.__file}'

Error message

No video stream found in file '{self.__file}'

What it means

VideoFromFile.get_size opens the file with PyAV and scans container.streams for a stream of type 'video'. If none exists (audio-only file, image file, corrupt container), it raises naming the file. This is a content-shape check on the input, done lazily when dimensions are first requested.

Source

Thrown at comfy_api/latest/_input_impl/video_types.py:161

        if start_time < 0:
            start_time = max(self._get_raw_duration() + start_time, 0.0)
        return float(start_time), float(self.__duration)

    def get_dimensions(self) -> tuple[int, int]:
        """
        Returns the dimensions of the video input.

        Returns:
            Tuple of (width, height)
        """
        if isinstance(self.__file, io.BytesIO):
            self.__file.seek(0)  # Reset the BytesIO object to the beginning
        with av.open(self.__file, mode='r') as container:
            for stream in container.streams:
                if stream.type == 'video':
                    assert isinstance(stream, av.VideoStream)
                    return stream.width, stream.height
        raise ValueError(f"No video stream found in file '{self.__file}'")

    def get_bit_depth(self) -> int:
        if isinstance(self.__file, io.BytesIO):
            self.__file.seek(0)  # Reset the BytesIO object to the beginning
        with av.open(self.__file, mode="r") as container:
            video_stream = container.streams.video[0] if len(container.streams.video) > 0 else None
            return video_stream_bit_depth(video_stream)

    def get_duration(self) -> float:
        """
        Returns the duration of the video in seconds.

        Returns:
            Duration in seconds
        """
        raw_duration = self._get_raw_duration()
        if self.__start_time < 0:
            duration_from_start = min(raw_duration, -self.__start_time)

View on GitHub (pinned to 1c6d8d45b3)

Solutions

  1. Confirm the file actually contains a video track (ffprobe file) and replace audio-only inputs
  2. Validate at ingest: check container.streams.video is non-empty before constructing downstream inputs
  3. If the file should have video, re-export it from the source editor (the export may have been audio-only)

Example fix

// before
vi = VideoFromFile('voiceover.m4a')
w, h = vi.get_size()  # ValueError

# after
import av
with av.open('voiceover.m4a') as c:
    assert c.streams.video, 'input must contain a video stream'
vi = VideoFromFile('clip.mp4')
Defensive patterns

Strategy: validation

Validate before calling

import av
with av.open(path) as c:
    if not c.streams.video:
        raise ValueError(f'{path} has no video stream')

Type guard

def has_video_stream(path) -> bool:
    import av
    with av.open(path) as c:
        return len(c.streams.video) > 0

Prevention

When it happens

Trigger: Constructing a VideoInput from a file that contains no video stream — an mp3/m4a/audio-only mp4, a GIF mislabeled, or a file PyAV demuxes but whose streams are all non-video — then calling get_size().

Common situations: User feeds an audio file into a video input node; upload validation only checked extension; the file is an HTML error page with media extension.

Related errors


AI-assisted analysis of Comfy-Org/ComfyUI@1c6d8d45b3 (2026-08-14). Data as JSON: /api/errors/42c5277f79b8736c. Report an issue: GitHub.