sgl-project/sglang · error · ValueError

Cosmos3 batched action input requires one prompt per image,

Error message

Cosmos3 batched action input requires one prompt per image, got {len(prompts)} prompt(s) and {batch_size} image(s)

What it means

For batched Cosmos3 action requests (multiple observation images), the number of prompts must equal the number of images, except a single prompt which is broadcast. This error fires when the prompt list length (after broadcast attempt) still mismatches the image batch size. It enforces one-prompt-per-image pairing so outputs stay aligned with inputs.

Source

Thrown at python/sglang/multimodal_gen/runtime/entrypoints/action/cosmos3.py:120

                "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:
        raise ValueError(
            "Cosmos3 batched action input requires one prompt per image, got "
            f"{len(prompts)} prompt(s) and {batch_size} image(s)"
        )
    return prompts[0] if batch_size == 1 else prompts


def build_cosmos3_action_sampling_params(
    payload: dict[str, Any],
    observation: dict[str, Any],
    server_args: ServerArgs,
    sampling_params_cls: type[Cosmos3SamplingParams],
) -> Cosmos3SamplingParams:
    parameters = dict(payload.get("parameters") or {})
    options = {**observation, **parameters}
    action_mode = str(options.get("action_mode", "policy")).strip().lower()
    if action_mode == "forward_dynamics":
        raise ValueError(
            "Cosmos3 forward_dynamics produces video; use /v1/videos instead"

View on GitHub (pinned to 0132848349)

Solutions

  1. Match len(prompt) == len(images), or provide exactly one prompt to broadcast
  2. Trim or extend the prompt list explicitly before the call: prompt = prompt[:len(images)] or pad with prompt[-1]
  3. Audit upstream batching code that zips images and prompts

Example fix

# before
prompt = ["a", "b"]
images = [img1, img2, img3]
# after
prompt = ["a", "b", "a"]  # len(prompt) == len(images)
Defensive patterns

Strategy: validation

Validate before calling

if isinstance(prompt, list):
    if len(prompt) == 1:
        prompt = prompt * len(images)
    assert len(prompt) == len(images), f'{len(prompt)} prompts vs {len(images)} images'

Prevention

When it happens

Trigger: Sending 3 images with a 2-element prompt list; sending batch_size>1 with an empty-ish or wrong-length list (lists of length !=1 and !=batch_size).

Common situations: Dropping one image from a batch but not its prompt; concatenating datasets where images and prompts desynchronize; assuming prompts are truncated/padded to image count.

Related errors


AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28). Data as JSON: /api/errors/884982eb6b5b2521. Report an issue: GitHub.