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
- Test decodability first: ffprobe -select_streams v -show_frames and confirm frames decode; re-download the file if truncated
- If the codec is exotic, install an ffmpeg/PyAV build with that decoder enabled (or re-encode to h264 externally)
- 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
- Verify decodability with ffprobe before feeding to transcode nodes
- Ensure your PyAV/ffmpeg build includes decoders for your input codecs
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
- Could not determine duration for file '{self.__file}'
- Video resolution changes mid-stream ({source_size[0]}x{sourc
- No video stream found in file '{self.__file}'
- H.264 output requires even dimensions, got {out_width}x{out_
- Video too short: need at least 16 frames for Moonvalley
AI-assisted analysis of Comfy-Org/ComfyUI@1c6d8d45b3 (2026-08-14).
Data as JSON: /api/errors/f05750e58c04cdbe.
Report an issue: GitHub.