{"record":{"id":"b6334ddef4e332fd","repo":"invoke-ai/InvokeAI","slug":"cannot-resolve-negative-frame-index-for-video-sel","errorCode":null,"errorMessage":"Cannot resolve negative frame index for video {self.video.video_name}: probe returned duration={duration}, fps={fps}.","messagePattern":"Cannot resolve negative frame index for video (.+?): probe returned duration=(.+?), fps=(.+?)\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"invokeai/app/invocations/video_frame_extract.py","lineNumber":59,"sourceCode":"        description=\"Index of the frame to extract. 0 = first frame, -1 = last frame, -2 = second-to-last, etc.\",\n        ui_component=UIComponent.VideoFrameIndex,\n    )\n\n    def invoke(self, context: InvocationContext) -> ImageOutput:\n        video_path = context.videos.get_path(self.video.video_name)\n\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":41,"sourceCodeEnd":76,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/app/invocations/video_frame_extract.py#L41-L76","documentation":"Thrown in VideoFrameExtract.invoke when frame_index is negative and the frame count cannot be resolved. It first tries decoder_frame_count; if that returns None it falls back to probing duration*fps, and raises when fps is 0/None or duration <= 0. Negative indexing is impossible without a reliable frame count.","triggerScenarios":"invoke() with frame_index < 0 where decoder_frame_count(path) returns None and probe_video(path) yields invalid fps or duration (fps falsy or duration <= 0).","commonSituations":"Corrupt or unusual containers that ffmpeg probe cannot measure; live streams or pipes with unknown duration; codec metadata missing fps.","solutions":["Use a non-negative frame_index","Re-encode the video to a standard MP4/H.264 file so probe can read duration and fps","Verify the source file is complete and not a stream/pipe","Check the video plays and reports duration via ffprobe"],"exampleFix":"// before\nVideoFrameExtract(video=v, frame_index=-1)  # probe returns fps=0\n// after\nVideoFrameExtract(video=v, frame_index=0)  # or fix source encoding","handlingStrategy":"validation","validationCode":"probe = probe_video(path)\nif frame_index < 0 and (not probe.fps or probe.duration <= 0) and decoder_frame_count(path) is None:\n    raise ValueError('cannot resolve negative frame index: probe invalid')","typeGuard":null,"tryCatchPattern":"try:\n    out = extract.invoke(context)\nexcept ValueError as e:\n    if 'Cannot resolve negative frame index' in str(e):\n        out = rebuild(frame_index=0).invoke(context)\n    else:\n        raise","preventionTips":["Prefer non-negative frame indices","Validate probe output (fps>0, duration>0) before negative indexing","Re-encode sources without duration metadata"],"tags":["video","negative-index","probe"],"backgroundTag":"unresolvable-frame-index","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}