sgl-project/sglang · error · ValueError
Cosmos3 observation image arrays must have shape [H, W] or [
Error message
Cosmos3 observation image arrays must have shape [H, W] or [H, W, C], got {tuple(item.shape)} What it means
numpy image arrays for Cosmos3 must be 2D grayscale [H, W] or 3D [H, W, C]; other ranks raise this ValueError with the offending shape. Note [B,H,W,C] batched arrays are handled elsewhere — per-item arrays here must be single images.
Source
Thrown at python/sglang/multimodal_gen/runtime/entrypoints/action/cosmos3.py:101
)
image = next(iter(images.values()))
if isinstance(image, (list, tuple)):
images = list(image)
elif isinstance(image, np.ndarray) and image.ndim == 4:
images = list(image)
else:
images = [image]
normalized_images: list[Any] = []
for item in images:
if not isinstance(item, np.ndarray):
normalized_images.append(item)
continue
if item.dtype != np.uint8:
raise ValueError("Cosmos3 observation image arrays must use uint8 dtype")
if item.ndim not in (2, 3):
raise ValueError(
"Cosmos3 observation image arrays must have shape [H, W] "
f"or [H, W, C], got {tuple(item.shape)}"
)
normalized_images.append(Image.fromarray(item))
return normalized_images
def _action_prompt(prompt: Any, batch_size: int) -> str | list[str]:
if isinstance(prompt, str):
return prompt if batch_size == 1 else [prompt] * batch_size
if not isinstance(prompt, (list, tuple)) or not prompt:
raise ValueError("Cosmos3 action prompt must be a string or non-empty list")
if not all(isinstance(item, str) for item in prompt):
raise ValueError("Cosmos3 action prompt list must contain only strings")
prompts = list(prompt)
if len(prompts) == 1 and batch_size > 1:
prompts *= batch_size
if len(prompts) != batch_size:View on GitHub (pinned to 0132848349)
Solutions
- Transpose/reshape to [H,W] or [H,W,C]: arr = arr.transpose(1,2,0) for CHW->HWC
- Remove batch/time dims: arr.squeeze() or arr[0] / arr[:, t]
- For batches, pass a list of [H,W,C] uint8 arrays
Example fix
# before image = chw_tensor.numpy() # shape [3, 224, 224] -> error # after image = chw_tensor.permute(1, 2, 0).numpy().astype(np.uint8) # [224, 224, 3]
Defensive patterns
Strategy: type-guard
Validate before calling
import numpy as np
def ensure_hwc_uint8(arr: np.ndarray) -> np.ndarray:
assert arr.ndim in (2, 3), f"bad image rank {arr.shape}"
if arr.ndim == 3 and arr.shape[0] in (1, 3) and arr.shape[0] < arr.shape[-1]:
arr = arr.transpose(1, 2, 0) # CHW -> HWC heuristic
return ensure_uint8(arr) Type guard
def is_valid_image_shape(a) -> bool:
return not isinstance(a, np.ndarray) or (a.dtype == np.uint8 and a.ndim in (2, 3)) Prevention
- Convert torch CHW tensors with .permute(1,2,0) before .numpy()
- Squeeze batch/time dims explicitly rather than relying on downstream handling
- Unit-test observation shapes against the API contract
When it happens
Trigger: Passing a [B,H,W,C] batched array that ends up iterated per-item incorrectly, a flattened [H*W] vector, [C,H,W] channel-first tensor converted to numpy, or an [H,W,C,T] video clip.
Common situations: Images converted from torch tensors keeping channel-first layout; video frames with an extra time dimension; already-batched arrays reaching a code path expecting single images.
Related errors
- Cosmos3 observation image arrays must use uint8 dtype
- Cosmos3 action input accepts one image field; use a list or
- Cosmos3 I2V image list is empty
- {name} must be a scalar tensor, got shape {tuple(scale.shape
- timestep must have shape [B, S, 9 * D]
AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28).
Data as JSON: /api/errors/69634b6167308102.
Report an issue: GitHub.