{"record":{"id":"f05750e58c04cdbe","repo":"Comfy-Org/ComfyUI","slug":"no-decodable-video-frames-found-in-file-self-f","errorCode":null,"errorMessage":"No decodable video frames found in file '{self.__file}'","messagePattern":"No decodable video frames found in file '(.+?)'","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"comfy_api/latest/_input_impl/video_types.py","lineNumber":773,"sourceCode":"                            audio_started = True\n                            if duration and frame_start > start_time:\n                                duration_cap = min(duration_cap, math.ceil((start_time + duration - frame_start) * sample_rate))\n                            if to_skip:\n                                pending_audio.append(audio_frame_from_ndarray(resampled.to_ndarray()[..., to_skip:]))\n                                continue\n                        pending_audio.append(resampled)\n                        if video_done:\n                            # the video window is complete so the cap is final, but containers\n                            # that interleave audio behind video (fragmented mp4) still owe most\n                            # of it: stop only once the demuxed audio covers the cap\n                            cap = drain_audio()\n                            if pending_audio or samples_written >= cap:\n                                drain_audio(final=True)\n                                audio_done = True\n                                break\n\n            if output is None:\n                raise ValueError(f\"No decodable video frames found in file '{self.__file}'\")\n            if out_audio is not None and not audio_done:\n                drain_audio(final=True)\n            window_fill = last_video_end - last_video_pts if video_done and last_video_pts is not None else 0\n            for out_packet in out_video.encode(None):\n                duration = video_frame_durations.pop(out_packet.pts, 0)\n                if out_packet.pts == last_video_pts:\n                    duration = max(duration, window_fill)\n                out_packet.duration = duration\n                output.mux(out_packet)\n            if out_audio is not None:\n                output.mux(out_audio.encode(None))\n        except BaseException:\n            if output is not None:\n                output.close()\n                if isinstance(path, (str, os.PathLike)) and os.path.exists(path):\n                    os.remove(path)\n            raise\n        else:","sourceCodeStart":755,"sourceCodeEnd":791,"githubUrl":"https://github.com/Comfy-Org/ComfyUI/blob/1c6d8d45b3693bfbb32385b410d813a7fd6be216/comfy_api/latest/_input_impl/video_types.py#L755-L791","documentation":"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.","triggerScenarios":"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.","commonSituations":"See trigger scenarios.","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"],"exampleFix":"// before\nvideo_input.save_transcoded('out.mp4')  # zero decodable frames\n\n# after\n# recover what decodes: ffmpeg -err_detect ignore_err -i in.mp4 -c:v libx264 recovered.mp4\nVideoFromFile('recovered.mp4').save_transcoded('out.mp4')","handlingStrategy":"validation","validationCode":"import av\nwith av.open(path) as c:\n    s = c.streams.video[0] if c.streams.video else None\n    if s is None or next(c.decode(s), None) is None:\n        raise ValueError('no decodable video frames; file truncated or codec unsupported')","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Verify decodability with ffprobe before feeding to transcode nodes","Ensure your PyAV/ffmpeg build includes decoders for your input codecs"],"tags":["video","transcode","no-decodable-frames","corrupt-file","pyav"],"backgroundTag":null,"analyzedSha":"1c6d8d45b3693bfbb32385b410d813a7fd6be216","analyzedAt":"2026-08-14T19:37:18.893Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}