{"record":{"id":"14aac5a5cdd9a4eb","repo":"invoke-ai/InvokeAI","slug":"failed-to-extract-frame-index-from-self-video-v","errorCode":null,"errorMessage":"Failed to extract frame {index} from {self.video.video_name}.","messagePattern":"Failed to extract frame (.+?) from (.+?)\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"invokeai/app/invocations/video_frame_extract.py","lineNumber":72,"sourceCode":"        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":54,"sourceCodeEnd":76,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/app/invocations/video_frame_extract.py#L54-L76","documentation":"Thrown when extract_video_frame returned None despite a valid index, i.e. the decoder could not actually produce the requested frame. This separates 'the index was valid' from 'decoding succeeded' failures.","triggerScenarios":"invoke(): index passed validation, but extract_video_frame(video_path, frame_index=index) returns None (decoder error at seek/decode time, e.g. index beyond actual decodable frames despite metadata count).","commonSituations":"Metadata frame count (duration*fps estimate) exceeding real decodable frames; corrupted frames mid-file; VFR videos where duration*fps overestimates.","solutions":["Clamp index to decoder_frame_count(path) rather than the probe estimate","Re-encode the video with ffmpeg to repair decode errors","Retry with a nearby frame index","Use an exact frame count from decoding instead of duration*fps"],"exampleFix":"// before\nindex = int(round(duration * fps)) - 1  # estimate can exceed real frames\n// after\nn = decoder_frame_count(path)\nindex = min(index, (n or 1) - 1)","handlingStrategy":"retry","validationCode":"n = decoder_frame_count(path)\nif n is not None:\n    index = min(index, n - 1)","typeGuard":null,"tryCatchPattern":"try:\n    out = extract.invoke(context)\nexcept ValueError as e:\n    if 'Failed to extract frame' in str(e):\n        out = rebuild(frame_index=max(0, index - 1)).invoke(context)  # retry nearby frame\n    else:\n        raise","preventionTips":["Clamp index to decoder_frame_count, not duration*fps estimates","Re-encode sources with decode errors","Keep a fallback index (e.g. frame 0) for critical pipelines"],"tags":["video","decoding","frame-extraction"],"backgroundTag":"frame-decode-failed","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}