{"record":{"id":"346aacf75be6bd5e","repo":"sgl-project/sglang","slug":"the-number-of-image-placeholders-exceeds-img-grid","errorCode":null,"errorMessage":"The number of image placeholders exceeds img_grid_thw entries.","messagePattern":"The number of image placeholders exceeds img_grid_thw entries\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/multimodal/processors/kimi_common.py","lineNumber":110,"sourceCode":"\n        if not isinstance(prompt, list):\n            prompt = self._tokenizer.encode(prompt)\n\n        image_token_counts = [\n            self._num_image_tokens_from_grid(grid) for grid in img_grid_thw\n        ]\n\n        input_ids = []\n        offsets = []\n        img_idx = 0\n\n        for token in prompt:\n            if token != image_token_id:\n                input_ids.append(token)\n                continue\n\n            if img_idx >= len(image_token_counts):\n                raise ValueError(\n                    \"The number of image placeholders exceeds img_grid_thw entries.\"\n                )\n\n            num_tokens = image_token_counts[img_idx]\n            start = len(input_ids)\n            input_ids.extend([image_token_id] * num_tokens)\n            offsets.append((start, len(input_ids) - 1))\n            img_idx += 1\n\n        if img_idx != len(image_token_counts):\n            raise ValueError(\n                \"The number of image placeholders does not match img_grid_thw entries.\"\n            )\n\n        image_embeddings = embeddings[Modality.IMAGE]\n        mm_items = []\n        consumed = 0\n        for start, end in offsets:","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/multimodal/processors/kimi_common.py#L92-L128","documentation":"While expanding Kimi image placeholders into per-image token spans, the input prompt contains more image_token_id tokens than there are img_grid_thw entries. The loop runs out of grid-derived token counts and cannot fill the next placeholder, so it raises.","triggerScenarios":"Calling get_mm_data / _build_kimi_mm_data_from_grids where the tokenized prompt has N image placeholder tokens but image_token_counts (from img_grid_thw) has fewer than N entries.","commonSituations":"Hardcoded prompts with extra <img> tokens, chat templates emitting one placeholder per image while the client sent fewer images/grids, or stale tokenized prompts reused after the image list changed.","solutions":["Make the number of placeholder tokens in the prompt equal len(img_grid_thw) / the number of images","Regenerate the prompt with the current chat template after changing the image list","Add a pre-flight assert: placeholder_count == len(image_token_counts)"],"exampleFix":"// before\nprompt = f\"{IMG} {IMG} look\"  # 2 placeholders, 1 image\nbuild_from_grids(prompt, grids=[g1])\n\n// after\nprompt = f\"{IMG} look\"  # 1 placeholder, 1 image\nbuild_from_grids(prompt, grids=[g1])","handlingStrategy":"validation","validationCode":"n_ph = sum(1 for t in input_ids if t == image_token_id)\nassert n_ph <= len(image_token_counts), f\"{n_ph} placeholders > {len(image_token_counts)} grids\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep prompt placeholders and image lists generated together","Never hand-edit placeholder tokens into prompts","Pre-count placeholders on both token and text level"],"tags":["kimi","multimodal","placeholder-count","validation"],"backgroundTag":"multimodal-placeholder-mismatch","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}