Comfy-Org/ComfyUI · error · ValueError

No decodable video frames found in file '{self.__file}'

Error message

No decodable video frames found in file '{self.__file}'

What it means

The transcode routine lazily creates the output container when the first decodable video frame arrives. If the demux loop finishes without producing any decodable frame (video stream exists but is empty or fully corrupt), output is still None and the code raises 'No decodable video frames found' — distinct from 'No video stream found', which fires when there is no video track at all.

Source

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

                            audio_started = True
                            if duration and frame_start > start_time:
                                duration_cap = min(duration_cap, math.ceil((start_time + duration - frame_start) * sample_rate))
                            if to_skip:
                                pending_audio.append(audio_frame_from_ndarray(resampled.to_ndarray()[..., to_skip:]))
                                continue
                        pending_audio.append(resampled)
                        if video_done:
                            # the video window is complete so the cap is final, but containers
                            # that interleave audio behind video (fragmented mp4) still owe most
                            # of it: stop only once the demuxed audio covers the cap
                            cap = drain_audio()
                            if pending_audio or samples_written >= cap:
                                drain_audio(final=True)
                                audio_done = True
                                break

            if output is None:
                raise ValueError(f"No decodable video frames found in file '{self.__file}'")
            if out_audio is not None and not audio_done:
                drain_audio(final=True)
            window_fill = last_video_end - last_video_pts if video_done and last_video_pts is not None else 0
            for out_packet in out_video.encode(None):
                duration = video_frame_durations.pop(out_packet.pts, 0)
                if out_packet.pts == last_video_pts:
                    duration = max(duration, window_fill)
                out_packet.duration = duration
                output.mux(out_packet)
            if out_audio is not None:
                output.mux(out_audio.encode(None))
        except BaseException:
            if output is not None:
                output.close()
                if isinstance(path, (str, os.PathLike)) and os.path.exists(path):
                    os.remove(path)
            raise
        else:

View on GitHub (pinned to 1c6d8d45b3)

Solutions

  1. Test decodability first: ffprobe -select_streams v -show_frames and confirm frames decode; re-download the file if truncated
  2. If the codec is exotic, install an ffmpeg/PyAV build with that decoder enabled (or re-encode to h264 externally)
  3. Remux with ffmpeg -err_detect ignore_err -i in.mp4 -c copy out.mp4 to strip corrupt packets, then retry

Example fix

// before
video_input.save_transcoded('out.mp4')  # zero decodable frames

# after
# recover what decodes: ffmpeg -err_detect ignore_err -i in.mp4 -c:v libx264 recovered.mp4
VideoFromFile('recovered.mp4').save_transcoded('out.mp4')
Defensive patterns

Strategy: validation

Validate before calling

import av
with av.open(path) as c:
    s = c.streams.video[0] if c.streams.video else None
    if s is None or next(c.decode(s), None) is None:
        raise ValueError('no decodable video frames; file truncated or codec unsupported')

Prevention

When it happens

Trigger: Calling the save/transcode path on a file that has a video stream entry but zero decodable frames — truncated mid-first-GOP downloads, header-only files, or codec unsupported by the installed PyAV/ffmpeg build.

Common situations: See trigger scenarios.

Related errors


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