{"record":{"id":"bd5a54b12bc4c511","repo":"sgl-project/sglang","slug":"expected-one-kimi-k3-image-span-for-each-image","errorCode":null,"errorMessage":"Expected one Kimi-K3 image span for each image","messagePattern":"Expected one Kimi-K3 image span for each image","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/multimodal/processors/kimi_k3.py","lineNumber":468,"sourceCode":"            processed_bytes += 3 * padded_width * padded_height * torch.float32.itemsize\n\n        return raw_bytes <= processed_bytes\n\n    def _build_deferred_output(self, base_output):\n        (\n            input_ids,\n            resize_configs,\n            deferred_preprocessing,\n        ) = self._processor.prepare_deferred(\n            base_output.input_text,\n            base_output.images,\n            base_output.input_ids,\n        )\n        offsets = self.get_mm_items_offset(\n            input_ids.flatten(), self.mm_tokens.image_token_id\n        )\n        if len(offsets) != len(base_output.images):\n            raise ValueError(\"Expected one Kimi-K3 image span for each image\")\n\n        items = []\n        for image, resize_config, offset in zip(\n            base_output.images, resize_configs, offsets\n        ):\n            grid_thw = _grid_thw_from_resize_config(\n                resize_config, self._processor.preprocess_config.patch_size\n            )\n            item = MultimodalDataItem(\n                modality=Modality.IMAGE,\n                feature=to_chw_uint8(image),\n                offsets=[offset],\n                model_specific_data={\n                    \"image_grid_thw\": torch.tensor([grid_thw], dtype=torch.int64),\n                    DEFERRED_PREPROCESSING_KEY: deferred_preprocessing(\n                        resize_config=resize_config\n                    ),\n                },","sourceCodeStart":450,"sourceCodeEnd":486,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/multimodal/processors/kimi_k3.py#L450-L486","documentation":"Raised in _build_deferred_output when the number of image-token spans found in input_ids does not equal the number of loaded images, before deferring GPU preprocessing. Each loaded image needs exactly one placeholder span to attach its deferred artifact.","triggerScenarios":"_process_mm_data_uncached with GPU preprocessing deferred and base_output.images length != number of image_token_id offsets in input_ids; usually a placeholder-mismatch that slipped past earlier checks or offsets merged after token expansion.","commonSituations":"Prompt template emits adjacent image tokens that merge into one span; images filtered/deduplicated during loading so base_output.images count changed.","solutions":["Ensure exactly one image placeholder per image in the prompt","Check that image loading (load_mm_data) does not drop or merge images","Verify get_mm_items_offset isn't collapsing consecutive placeholder tokens; keep separators between images"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"def check_spans(processor, input_ids, images):\n    offs = processor.get_mm_items_offset(input_ids.flatten(), processor.mm_tokens.image_token_id)\n    return len(offs) == len(images)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Separate consecutive image placeholders with text so spans don't merge","Never drop images between loading and composition"],"tags":["multimodal","kimi-k3","deferred-preprocessing","span-mismatch"],"backgroundTag":"multimodal-placeholder-count-mismatch","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}