sgl-project/sglang · error · ValueError

QwenImageEditPlus expects either one shared condition image

Error message

QwenImageEditPlus expects either one shared condition image or the same number of condition images and prompts.

What it means

QwenImageEditPlus supports exactly two valid image/prompt pairings: one shared condition image broadcast to all prompts, or a 1:1 list of condition images per prompt. Any other count mismatch (2..N-1 images vs M prompts where N != M) is rejected with this ValueError during image-processor kwargs preparation.

Source

Thrown at python/sglang/multimodal_gen/configs/pipeline_configs/qwen_image.py:99

    if images is None:
        return []
    return images if isinstance(images, list) else [images]


def _build_qwen_edit_image_prompt(num_images: int) -> str:
    img_prompt_template = "Picture {}: <|vision_start|><|image_pad|><|vision_end|>"
    return "".join(img_prompt_template.format(i + 1) for i in range(num_images))


def _resolve_qwen_edit_per_prompt_images(prompt_list, image_list):
    if len(prompt_list) <= 1:
        return [image_list]

    if len(image_list) <= 1:
        return [list(image_list) for _ in prompt_list]

    if len(image_list) != len(prompt_list):
        raise ValueError(
            "QwenImageEditPlus expects either one shared condition image or "
            "the same number of condition images and prompts."
        )

    return [[image] for image in image_list]


def _shard_qwen_edit_img_cache_for_sp(
    img_cache: torch.Tensor, noisy_img_seq_len: int, device: torch.device
) -> torch.Tensor:
    noisy_img_cache = shard_rotary_emb_for_sp(img_cache[:noisy_img_seq_len, :])
    condition_img_cache = shard_rotary_emb_for_sp(img_cache[noisy_img_seq_len:, :])
    return torch.cat([noisy_img_cache, condition_img_cache], dim=0).to(device=device)


def _shard_qwen_edit_freqs_cis_for_sp(freqs_cis, noisy_img_seq_len, device):
    if isinstance(freqs_cis[0], torch.Tensor) and freqs_cis[0].dim() == 2:
        img_cache, txt_cache = freqs_cis

View on GitHub (pinned to 0132848349)

Solutions

  1. Use a single shared image broadcast to all prompts: image=[one_pil_image]
  2. Or make counts exactly equal: len(image) == len(prompt), one image per prompt
  3. If prompts need different image counts, run separate requests per prompt (one call per prompt with its own image list)

Example fix

# before
images = [img1, img2]
prompts = ["edit a", "edit b", "edit c"]
pipe(prompt=prompts, image=images)  # 2 images vs 3 prompts -> error

# after
images = [img1, img2, img3]
pipe(prompt=prompts, image=images)  # 1:1 counts
Defensive patterns

Strategy: validation

Validate before calling

images, prompts = list(images), list(prompts)
assert len(images) == 1 or len(images) == len(prompts), (
    f"need 1 shared image or {len(prompts)} images, got {len(images)}")

Try / catch

try:
    kwargs = pipe.prepare_image_processor_kwargs(images, prompts)
except ValueError as e:
    if "same number of condition images and prompts" in str(e):
        # split into per-prompt calls
        results = [pipe(p, image=[i] if len(images) > 1 else images) for p, i in zip(prompts, images)]
    else:
        raise

Prevention

When it happens

Trigger: Calling QwenImageEditPlus generation with e.g. 3 images and 5 prompts (neither 1 nor equal counts); passing image=[img1, img2] with a batch of 3 prompt strings.

Common situations: Building a batch edit request where some prompts have multiple images and others one; accidentally flattening nested image lists so the length no longer matches the prompt batch; dynamic UIs letting users attach arbitrary image counts per prompt.

Related errors


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