invoke-ai/InvokeAI · error · ValueError
Decoded frame must be RGB; got shape {frame.shape}
Error message
Decoded frame must be RGB; got shape {frame.shape} What it means
_validate_decoded_frame checks that a decoded video frame is a 3-dimensional RGB ndarray (H, W, 3). OpenCV decodes frames as BGR with shape (H, W, 3), but frames arriving here are expected to have been converted to RGB; a grayscale, RGBA, or non-array frame fails this check. It is a defensive invariant check on the decode pipeline.
Source
Thrown at invokeai/app/util/video_decode_worker.py:71
if sys.platform != "linux":
return
try:
import os
import resource
pages = int(Path("/proc/self/statm").read_text().split()[0])
limit = pages * os.sysconf("SC_PAGE_SIZE") + WORKER_MEMORY_HEADROOM_BYTES
_soft, hard = resource.getrlimit(resource.RLIMIT_AS)
if hard != resource.RLIM_INFINITY:
limit = min(limit, hard)
resource.setrlimit(resource.RLIMIT_AS, (limit, hard))
except (OSError, ValueError):
pass
def _validate_decoded_frame(frame: np.ndarray) -> None:
if frame.ndim != 3 or frame.shape[2] != 3:
raise ValueError(f"Decoded frame must be RGB; got shape {frame.shape}")
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:View on GitHub (pinned to 0b6a024f2f)
Solutions
- Convert BGR frames to RGB with cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) before validating
- For grayscale videos, stack or cv2.cvtColor(cv2.COLOR_GRAY2RGB) before passing the frame
- Check the decoder path producing the frame and ensure it always yields (H, W, 3) uint8 RGB arrays
Example fix
// before _validate_decoded_frame(frame_bgr) // after frame_rgb = cv2.cvtColor(frame_bgr, cv2.COLOR_BGR2RGB) _validate_decoded_frame(frame_rgb)
Defensive patterns
Strategy: validation
Validate before calling
def is_rgb_frame(f) -> bool:
return isinstance(f, np.ndarray) and f.ndim == 3 and f.shape[2] == 3 Type guard
def is_rgb_frame(f: object) -> bool:
return isinstance(f, np.ndarray) and f.ndim == 3 and f.shape[2] == 3 Try / catch
try:
_validate_decoded_frame(frame)
except ValueError as e:
if "must be RGB" in str(e):
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
_validate_decoded_frame(frame)
else:
raise Prevention
- Always convert BGR to RGB immediately after cv2.VideoCapture().read()
- Normalize grayscale/alpha frames to RGB before the pipeline
- Keep frame arrays uint8 (H, W, 3) end-to-end
- Add a shape assertion at decoder boundaries
When it happens
Trigger: A decoder returns a grayscale frame (ndim==2), an RGBA frame (shape[2]==4), or a non-RGB array passed to _validate_decoded_frame without cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) conversion.
Common situations: Forgetting cv2.COLOR_BGR2RGB conversion when switching between cv2 and imageio/PIL paths; videos with alpha channels or grayscale codecs; a decoder returning None or a differently-shaped array due to codec quirks.
Related errors
- Decoded frame dimensions {width}x{height} exceed the maximum
- Unable to validate video dimensions for {video_path}
- Video reports invalid dimensions {width}x{height}
- Unable to open video at {video_path}
- No frames decoded from {video_path}
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/060d4118885f5031.
Report an issue: GitHub.