invoke-ai/InvokeAI · error · ValueError
Unexpected cond image shape: {tuple(rgb_bchw_01.shape)} (exp
Error message
Unexpected cond image shape: {tuple(rgb_bchw_01.shape)} (expected B,3,H,W) What it means
prepare_cond_image converts an RGB conditioning image shaped (B,3,H,W) in [0,1] into the tensor ControlNet-LLLite expects, resizing to the latent-derived target. It raises ValueError when the tensor is not 4-D or its channel dimension is not 3 — i.e. it was passed grayscale, batched-with-alpha, or wrongly permuted data.
Source
Thrown at invokeai/backend/anima/control_net_lllite.py:80
def target_cond_hw(latent_h: int, latent_w: int, patch_spatial: int = 2) -> tuple[int, int]:
"""Return the (H, W) the cond image / mask must be resized to.
The LLLite ``conditioning1`` trunk has total conv stride 16, so the cond
image must be sized to ``latent_HW * 8`` in input pixel space (= token_HW
* 16 after DiT patchify with patch_spatial=2). The DiT internally pads the
latent up to a multiple of ``patch_spatial`` before patchify, so the same
rounding is mirrored here — otherwise odd latent dims yield a token-count
mismatch that silently bypasses every LLLite module.
"""
padded_h = ((latent_h + patch_spatial - 1) // patch_spatial) * patch_spatial
padded_w = ((latent_w + patch_spatial - 1) // patch_spatial) * patch_spatial
return padded_h * 8, padded_w * 8
def prepare_cond_image(rgb_bchw_01: torch.Tensor, latent_h: int, latent_w: int, patch_spatial: int = 2) -> torch.Tensor:
"""RGB image (B, 3, H, W) in [0, 1] -> (1, 3, H_t, W_t) in [-1, 1]."""
if rgb_bchw_01.ndim != 4 or rgb_bchw_01.shape[1] != 3:
raise ValueError(f"Unexpected cond image shape: {tuple(rgb_bchw_01.shape)} (expected B,3,H,W)")
img = rgb_bchw_01[:1]
target_h, target_w = target_cond_hw(latent_h, latent_w, patch_spatial)
if img.shape[-2] != target_h or img.shape[-1] != target_w:
img = F.interpolate(img, size=(target_h, target_w), mode="bicubic", align_corners=False)
img = img.clamp(0.0, 1.0)
return img * 2.0 - 1.0
def prepare_mask(mask_b1hw_01: torch.Tensor, latent_h: int, latent_w: int, patch_spatial: int = 2) -> torch.Tensor:
"""Mask (B, 1, H, W) or (B, H, W) in [0, 1] -> (1, 1, H_t, W_t) in {0.0, 1.0}.
1 = inpaint area, 0 = keep. The caller is responsible for the ``*2-1``
rescale before concat with RGB (see :func:`build_inpaint_cond_image`).
"""
if mask_b1hw_01.ndim == 3:
m = mask_b1hw_01.unsqueeze(1)
elif mask_b1hw_01.ndim == 4 and mask_b1hw_01.shape[1] == 1:
m = mask_b1hw_01View on GitHub (pinned to 0b6a024f2f)
Solutions
- Ensure input is a float tensor with shape (B,3,H,W) and values in [0,1].
- If shape is (H,W,3) or (3,H,W), add/permute: img.permute(2,0,1).unsqueeze(0).
- Convert grayscale to RGB with .repeat(1,3,1,1) and drop alpha channels.
- Validate with a guard before calling (see validationCode).
Example fix
# before cond = prepare_cond_image(image_np.transpose(2, 0, 1), latent_h, latent_w) # after import torch img = torch.from_numpy(image_np).permute(2, 0, 1).unsqueeze(0).float() / 255.0 assert img.shape[1] == 3, img.shape cond = prepare_cond_image(img, latent_h, latent_w)
Defensive patterns
Strategy: validation
Validate before calling
import torch
def validate_cond_image(img: torch.Tensor) -> None:
if not isinstance(img, torch.Tensor):
raise TypeError("cond image must be a torch.Tensor")
if img.ndim != 4 or img.shape[1] != 3:
raise ValueError(f"expected (B,3,H,W), got {tuple(img.shape)}")
if img.min() < 0.0 or img.max() > 1.0:
raise ValueError("cond image values must be in [0,1]") Type guard
def is_rgb_bchw(t) -> bool:
import torch
return isinstance(t, torch.Tensor) and t.ndim == 4 and t.shape[1] == 3 Try / catch
try:
cond = prepare_cond_image(img, latent_h, latent_w)
except ValueError as e:
raise ValueError(f"bad conditioning image: {e}; provide float (B,3,H,W) in [0,1]") from e Prevention
- Always convert HWC->CHW and add batch dim after PIL/cv2 load.
- Convert RGBA to RGB (drop alpha).
- Normalize to [0,1] (divide by 255 for uint8 inputs).
- Unit-test the preprocessing pipeline with shape assertions.
When it happens
Trigger: Calling prepare_cond_image (directly or via _build_lllite_cond_image) with a tensor of shape (3,H,W) (missing batch dim), (B,1,H,W) grayscale, (B,H,W,3) NHWC layout, or ndim != 4.
Common situations: Loading images via PIL/cv2 and forgetting to permute HWC->CHW, passing a mask instead of an RGB image, passing a batch of 1 without the leading dimension, or using a 4-channel RGBA image.
Understand the failure class
Background: Tensor shape mismatch errors ("must have shape", "expected shape ... got ..."): when tensor dimensions disagree with what an op or layer was told to expect — this error's family across 6 libraries.
Related errors
- Unexpected mask shape: {tuple(mask_b1hw_01.shape)} (expected
- LLLite module '{m.lllite_name}' was trained for in_features=
- Latent spatial dims must be even, got {h}x{w}
- The Anima ControlNet-LLLite model '{lllite_field.control_mod
- This Anima ControlNet-LLLite adapter is an inpainting adapte
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/ed1fd6988b5f64ce.
Report an issue: GitHub.