invoke-ai/InvokeAI · error · ValueError

Video {self.video.video_name} has no decodable frames (probe

Error message

Video {self.video.video_name} has no decodable frames (probed {n_frames}).

What it means

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.

Source

Thrown at invokeai/app/invocations/video_frame_extract.py:65

        # Resolve negative indices against the actual frame count rather than
        # trusting imageio plugins to accept index=-1 uniformly. Use the decoder's
        # frame count when available — duration*fps can be off-by-one for VFR
        # uploads or containers with approximate metadata, causing frame_index=-1
        # to point past the final frame.
        index = self.frame_index
        if index < 0:
            n_frames = decoder_frame_count(video_path)
            if n_frames is None:
                _, _, duration, fps = probe_video(video_path)
                if not fps or duration <= 0:
                    raise ValueError(
                        f"Cannot resolve negative frame index for video {self.video.video_name}: "
                        f"probe returned duration={duration}, fps={fps}."
                    )
                n_frames = int(round(duration * fps))
            if n_frames <= 0:
                raise ValueError(f"Video {self.video.video_name} has no decodable frames (probed {n_frames}).")
            index = n_frames + index
            if index < 0:
                raise ValueError(f"frame_index {self.frame_index} is out of range for a {n_frames}-frame video.")

        frame = extract_video_frame(video_path, frame_index=index)
        if frame is None:
            raise ValueError(f"Failed to extract frame {index} from {self.video.video_name}.")

        image_dto = context.images.save(image=frame)
        return ImageOutput.build(image_dto=image_dto)

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Verify the video contains actual frames (plays in a player)
  2. Re-encode the source with ffmpeg to a healthy file
  3. Use a non-negative frame_index to bypass count resolution (extraction will still fail later if truly empty)
  4. Regenerate or re-export the video from the source tool

Example fix

// before
VideoFrameExtract(video=empty_recording, frame_index=-1)  # probed n_frames=0
// after
VideoFrameExtract(video=valid_recording, frame_index=-1)
Defensive patterns

Strategy: validation

Validate before calling

n = decoder_frame_count(path)
if n is not None and n <= 0:
    raise ValueError(f'{path} has no decodable frames')

Type guard

def is_decodable(n_frames: int | None) -> bool:
    return n_frames is not None and n_frames > 0

Try / catch

try:
    out = extract.invoke(context)
except ValueError as e:
    if 'no decodable frames' in str(e):
        raise RuntimeError(f'source {video.video_name} is unusable; re-encode it') from e
    raise

Prevention

When it happens

Trigger: invoke() with frame_index < 0: either decoder_frame_count returns <= 0 or duration*fps rounds to 0.

Common situations: Empty/corrupt video files; zero-length recordings; pathological fps/duration metadata (e.g. 0 fps) in the container.

Related errors


AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29). Data as JSON: /api/errors/80ba9b843514ec1d. Report an issue: GitHub.