sgl-project/sglang · error · ValueError

Kimi image placeholders must map one-to-one to image data: e

Error message

Kimi image placeholders must map one-to-one to image data: expected {expected_image_count}, loaded {len(base_output.images)}

What it means

Kimi VL multimodal processor requires that the number of image placeholders in the prompt exactly equals the number of supplied image_data entries. After loading, the base processor returned a different count of images than expected, so a one-to-one mapping cannot be established.

Source

Thrown at python/sglang/srt/multimodal/processors/kimi_vl.py:44

            image_token_regex=re.compile(r"(?:<\|media_pad\|>)+"),
        ).build(_processor)

    async def process_mm_data_async(
        self,
        image_data: List[Union[str, bytes, Dict]],
        input_text,
        request_obj,
        *args,
        **kwargs,
    ):
        base_output = await self.load_mm_data(
            prompt=input_text,
            image_data=image_data,
            multimodal_tokens=self.mm_tokens,
        )
        expected_image_count = len(image_data or [])
        if len(base_output.images) != expected_image_count:
            raise ValueError(
                "Kimi image placeholders must map one-to-one to image data: "
                f"expected {expected_image_count}, loaded {len(base_output.images)}"
            )

        mm_items, input_ids, _ = await self.process_and_combine_mm_data_async(
            base_output, self.mm_tokens
        )

        return MultimodalProcessorOutput(
            input_ids=input_ids.tolist(),
            mm_items=mm_items,
            im_token_id=self.mm_tokens.image_token_id,
        )

    def get_mm_data(self, prompt, embeddings, **kwargs):
        img_grid_thw = kwargs.get("img_grid_thw", None)
        return self._build_kimi_mm_data_from_grids(
            prompt=prompt,

View on GitHub (pinned to 0132848349)

Solutions

  1. Make the number of image placeholders in the prompt text exactly match len(image_data)
  2. Verify each image item in the request maps to exactly one placeholder before submitting
  3. Check that image_data was not truncated or duplicated upstream in your client code

Example fix

# before
prompt = "<|START_OF_TURN|>[image]<|END_OF_TURN|> describe"  # 1 placeholder
image_data = [img1, img2]  # 2 images -> error
# after
prompt = "<|START_OF_TURN|>[image][image]<|END_OF_TURN|> describe"
image_data = [img1, img2]
Defensive patterns

Strategy: validation

Validate before calling

placeholder_count = prompt.count(image_placeholder_token)
assert placeholder_count == len(image_data), f"{placeholder_count} placeholders vs {len(image_data)} images"

Try / catch

catch ValueError around process_mm_data_async and surface a 400 with placeholder-vs-image counts to the client

Prevention

When it happens

Trigger: Calling process_mm_data_async on the Kimi VL processor where the prompt contains N image placeholder tokens but image_data has M != N entries (e.g. placeholder repeated, or image list truncated/duplicated before reaching the processor).

Common situations: Client sends an OpenAI-style request whose content array has more/fewer image_url parts than the (image_start_id...image_end_id) placeholder occurrences in the text template; or a middleware rewrites the prompt and breaks placeholder count.

Related errors


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