invoke-ai/InvokeAI · error · ValueError

Video dimensions {width}x{height} exceed the maximum decodab

Error message

Video dimensions {width}x{height} exceed the maximum decodable size

What it means

If probed width*height exceeds MAX_FRAME_PIXELS, the video is refused before decoding. This pre-decode check exists because the decoder allocates the full frame buffer, which the parent's frame-record bound and PIL checks only see after allocation — too late to prevent the memory spike.

Source

Thrown at invokeai/app/util/video_decode_worker.py:90

    height, width = frame.shape[:2]
    if height <= 0 or width <= 0 or height * width > MAX_FRAME_PIXELS:
        raise ValueError(f"Decoded frame dimensions {width}x{height} exceed the maximum decodable size")


def _assert_decodable_dims(video_path: Path) -> None:
    """Refuses to decode frames from a video whose reported dimensions exceed the bound.

    If the dimensions cannot be probed, decoding is refused because the parent's frame
    record bound and PIL checks run only after the decoder has allocated the frame.
    """
    try:
        width, height, _duration, _fps = _probe(video_path)[:4]
    except Exception as error:
        raise ValueError(f"Unable to validate video dimensions for {video_path}") from error
    if width <= 0 or height <= 0:
        raise ValueError(f"Video reports invalid dimensions {width}x{height}")
    if width * height > MAX_FRAME_PIXELS:
        raise ValueError(f"Video dimensions {width}x{height} exceed the maximum decodable size")


def _extract_frame(video_path: Path, frame_index: int) -> Optional[Image.Image]:
    """Extracts a single frame from a video file as a PIL Image. Returns None on failure.

    Tries imageio's FFMPEG plugin first since it's the same encoder we use for output,
    then falls back to cv2 — uploaded videos with unusual codecs may need that path.
    """
    try:
        # iio.imread with index=N seeks to that frame directly. Returns RGB HxWxC uint8.
        frame = iio.imread(video_path, plugin="FFMPEG", index=frame_index)
        _validate_decoded_frame(frame)
        return Image.fromarray(frame)
    except Exception:
        pass

    try:
        import cv2  # local import so the imageio-only path doesn't pay the cv2 import cost

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Re-encode the video to smaller dimensions (ffmpeg -vf scale=...) within the pixel budget
  2. Extract frames with a downscaling filter or a different tool and feed the worker the reduced video
  3. If the limit is too strict for your workload, raise MAX_FRAME_PIXELS consciously with the memory implications in mind

Example fix

// before
ffmpeg -i 8k_input.mp4 -c copy small.mp4  # stream copy keeps 8K

// after
ffmpeg -i 8k_input.mp4 -vf scale=3840:-2 small.mp4  # fits within pixel budget
Defensive patterns

Strategy: validation

Validate before calling

import cv2
def within_budget(path) -> bool:
    cap = cv2.VideoCapture(str(path))
    if not cap.isOpened():
        return False
    w, h = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
    cap.release()
    return w * h <= MAX_FRAME_PIXELS

Type guard

def within_budget(w: int, h: int) -> bool:
    return 0 < w and 0 < h and w * h <= MAX_FRAME_PIXELS

Try / catch

try:
    _assert_decodable_dims(video_path)
except ValueError as e:
    if "exceed the maximum decodable size" in str(e):
        video_path = downscale_video(video_path)  # ffmpeg -vf scale=...
    else:
        raise

Prevention

When it happens

Trigger: Decoding any video whose reported WxH product is above MAX_FRAME_PIXELS — e.g. 8K+ (7680x4320 ~33MP) or other very large sources — via main/_extract_frame paths that call _assert_decodable_dims.

Common situations: 8K/12K source footage; panorama or stitched videos; users pointing the worker at raw camera outputs.

Related errors


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