invoke-ai/InvokeAI · error · ValueError
Unsupported mask shape: {mask.shape}. Expected (1, h, w) or
Error message
Unsupported mask shape: {mask.shape}. Expected (1, h, w) or (h, w). What it means
to_standard_mask_dim normalizes a torch mask tensor to shape (1, h, w). It accepts a 2D (h, w) tensor or a 3D tensor whose first dim is exactly 1; anything else (e.g. (3, h, w), (b, 1, h, w), 4D tensors) triggers this ValueError. It exists to guarantee downstream regional-prompt masking code sees a uniform shape.
Source
Thrown at invokeai/backend/util/mask.py:19
import torch
def to_standard_mask_dim(mask: torch.Tensor) -> torch.Tensor:
"""Standardize the dimensions of a mask tensor.
Args:
mask (torch.Tensor): A mask tensor. The shape can be (1, h, w) or (h, w).
Returns:
torch.Tensor: The output mask tensor. The shape is (1, h, w).
"""
# Get the mask height and width.
if mask.ndim == 2:
mask = mask.unsqueeze(0)
elif mask.ndim == 3 and mask.shape[0] == 1:
pass
else:
raise ValueError(f"Unsupported mask shape: {mask.shape}. Expected (1, h, w) or (h, w).")
return mask
def to_standard_float_mask(mask: torch.Tensor, out_dtype: torch.dtype) -> torch.Tensor:
"""Standardize the format of a mask tensor.
Args:
mask (torch.Tensor): A mask tensor. The dtype can be any bool, float, or int type. The shape must be (1, h, w)
or (h, w).
out_dtype (torch.dtype): The dtype of the output mask tensor. Must be a float type.
Returns:
torch.Tensor: The output mask tensor. The dtype is out_dtype. The shape is (1, h, w). All values are either 0.0
or 1.0.
"""
View on GitHub (pinned to 0b6a024f2f)
Solutions
- Convert multi-channel masks to single channel: load with PIL Image.open(...).convert('L') or mask = mask.mean(dim=0) / mask[0].
- Squeeze or select the batch dim before calling: mask = mask.squeeze(1) or mask = mask[0].
- Call to_standard_float_mask with a (h, w) or (1, h, w) tensor only; loop over batch items otherwise.
Example fix
// before
mask = torch.stack([m1, m2]) # (2, h, w)
process(mask)
// after
for m in [m1, m2]:
process(to_standard_float_mask(m, torch.float32)) Defensive patterns
Strategy: type-guard
Validate before calling
def ensure_mask_shape(mask: torch.Tensor) -> torch.Tensor:
if mask.ndim == 3 and mask.shape[0] not in (1,):
mask = mask.mean(dim=0, keepdim=False) # RGB -> single channel
if mask.ndim > 3:
raise ValueError(f"mask must be (h,w) or (1,h,w), got {tuple(mask.shape)}")
return mask Type guard
def is_standard_mask(mask: torch.Tensor) -> bool:
return mask.ndim == 2 or (mask.ndim == 3 and mask.shape[0] == 1) Try / catch
try:
m = to_standard_float_mask(mask, torch.float32)
except ValueError as e:
if "Unsupported mask shape" in str(e):
m = to_standard_float_mask(mask.mean(dim=0) if mask.ndim == 3 else mask[0], torch.float32) Prevention
- Load mask images with PIL convert('L') so they are single-channel.
- Squeeze batch dims before passing masks to regional-prompt APIs.
- Keep one mask per tensor; never stack multiple regional masks.
When it happens
Trigger: Passing a mask with 4+ dims (batched), a 3-channel mask shaped (3, h, w) (e.g. an RGB mask image loaded without grayscale conversion), or a (n, h, w) stack with n > 1.
Common situations: Loading a mask PNG in RGB mode instead of 'L' mode, forgetting to squeeze a batch dimension after a dataloader/model, stacking multiple regional masks into one tensor.
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
- out_dtype must be a float type, but got {out_dtype}
- This Anima ControlNet-LLLite adapter is an inpainting adapte
- in_channels must be divisible by groups
- out_channels must be divisible by groups
- Cannot split QKV tensor '{key}': first dimension ({tensor.sh
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/375027035c9a0b22.
Report an issue: GitHub.