{"record":{"id":"80ba9b843514ec1d","repo":"invoke-ai/InvokeAI","slug":"video-self-video-video-name-has-no-decodable-fra","errorCode":null,"errorMessage":"Video {self.video.video_name} has no decodable frames (probed {n_frames}).","messagePattern":"Video (.+?) has no decodable frames \\(probed (.+?)\\)\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"invokeai/app/invocations/video_frame_extract.py","lineNumber":65,"sourceCode":"\n        # Resolve negative indices against the actual frame count rather than\n        # trusting imageio plugins to accept index=-1 uniformly. Use the decoder's\n        # frame count when available — duration*fps can be off-by-one for VFR\n        # uploads or containers with approximate metadata, causing frame_index=-1\n        # to point past the final frame.\n        index = self.frame_index\n        if index < 0:\n            n_frames = decoder_frame_count(video_path)\n            if n_frames is None:\n                _, _, duration, fps = probe_video(video_path)\n                if not fps or duration <= 0:\n                    raise ValueError(\n                        f\"Cannot resolve negative frame index for video {self.video.video_name}: \"\n                        f\"probe returned duration={duration}, fps={fps}.\"\n                    )\n                n_frames = int(round(duration * fps))\n            if n_frames <= 0:\n                raise ValueError(f\"Video {self.video.video_name} has no decodable frames (probed {n_frames}).\")\n            index = n_frames + index\n            if index < 0:\n                raise ValueError(f\"frame_index {self.frame_index} is out of range for a {n_frames}-frame video.\")\n\n        frame = extract_video_frame(video_path, frame_index=index)\n        if frame is None:\n            raise ValueError(f\"Failed to extract frame {index} from {self.video.video_name}.\")\n\n        image_dto = context.images.save(image=frame)\n        return ImageOutput.build(image_dto=image_dto)\n","sourceCodeStart":47,"sourceCodeEnd":76,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/app/invocations/video_frame_extract.py#L47-L76","documentation":"Thrown when the resolved frame count for the video is zero or negative. Negative frame_index resolution (or probe fallback) computed n_frames <= 0, meaning the video has no decodable frames. The library refuses to continue rather than produce a garbage extraction.","triggerScenarios":"invoke() with frame_index < 0: either decoder_frame_count returns <= 0 or duration*fps rounds to 0.","commonSituations":"Empty/corrupt video files; zero-length recordings; pathological fps/duration metadata (e.g. 0 fps) in the container.","solutions":["Verify the video contains actual frames (plays in a player)","Re-encode the source with ffmpeg to a healthy file","Use a non-negative frame_index to bypass count resolution (extraction will still fail later if truly empty)","Regenerate or re-export the video from the source tool"],"exampleFix":"// before\nVideoFrameExtract(video=empty_recording, frame_index=-1)  # probed n_frames=0\n// after\nVideoFrameExtract(video=valid_recording, frame_index=-1)","handlingStrategy":"validation","validationCode":"n = decoder_frame_count(path)\nif n is not None and n <= 0:\n    raise ValueError(f'{path} has no decodable frames')","typeGuard":"def is_decodable(n_frames: int | None) -> bool:\n    return n_frames is not None and n_frames > 0","tryCatchPattern":"try:\n    out = extract.invoke(context)\nexcept ValueError as e:\n    if 'no decodable frames' in str(e):\n        raise RuntimeError(f'source {video.video_name} is unusable; re-encode it') from e\n    raise","preventionTips":["Check files with ffprobe before ingestion","Reject zero-byte or header-only uploads","Re-encode all inputs to H.264 MP4 at ingest time"],"tags":["video","decoding","frame-count"],"backgroundTag":"empty-video-frames","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}