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
- Make the number of image placeholders in the prompt text exactly match len(image_data)
- Verify each image item in the request maps to exactly one placeholder before submitting
- 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
- Generate the prompt template from the image list length, not independently
- Validate placeholder count equals image count at request-build time
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
- Z-Image text embeddings must have shape [seq, dim] or [batch
- Cosmos3 action input accepts one image field; use a list or
- When using multiple prompts with multiple input images, prov
- f"Unsupported patch_size type: {type(patch_size)}"
- f"Expected camera embedding shape [B, C, F, H, W], got {tupl
AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28).
Data as JSON: /api/errors/1b14cd49cd26d752.
Report an issue: GitHub.