{"record":{"id":"b5bbf365fff6200f","repo":"sgl-project/sglang","slug":"dots-note-omni-requires-a-text-prompt-for-multimod","errorCode":null,"errorMessage":"Dots note omni requires a text prompt for multimodal requests","messagePattern":"Dots note omni requires a text prompt for multimodal requests","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/multimodal/processors/dots_note_omni.py","lineNumber":388,"sourceCode":"            pass\n        return \"\".join(rendered), ordered_images, ordered_audios\n\n    async def process_mm_data_async(\n        self,\n        input_text: list[int] | str,\n        request_obj: GenerateReqInput,\n        max_req_input_len: int,\n        *args,\n        image_data: list | None = None,\n        audio_data: list | None = None,\n        video_data=None,\n        **kwargs,\n    ):\n        video_data = request_obj.video_data or video_data\n        if not image_data and not audio_data and not video_data:\n            return None\n        if not isinstance(input_text, str):\n            raise ValueError(  # noqa: TRY004 - preserve the processor API contract\n                \"Dots note omni requires a text prompt for multimodal requests\"\n            )\n\n        request_videos = len(video_data) if video_data else 0\n        request_images = len(image_data) if image_data else 0\n        request_audios = len(audio_data) if audio_data else 0\n        logger.info(\n            \"[dots_mm] rid=%s request videos=%d images=%d audios=%d\",\n            request_obj.rid,\n            request_videos,\n            request_images,\n            request_audios,\n        )\n\n        if video_data:\n            video_config = dict(request_obj.video_config or {})\n            question = video_config.pop(\"_question\", \"\") or \"\"\n            seq = video_config.pop(\"seq\", 131072)","sourceCodeStart":370,"sourceCodeEnd":406,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/multimodal/processors/dots_note_omni.py#L370-L406","documentation":"Raised by process_mm_data_async when a multimodal request (image/audio/video data present) has a non-string input_text (e.g. a chat-messages list). The Dots Note Omni processor requires the already-rendered text prompt.","triggerScenarios":"Calling the /generate-style API with image_data/video_data set while passing input_text as a list of chat messages instead of a string; the processor checks isinstance(input_text, str) right after detecting mm data.","commonSituations":"Using the OpenAI-compatible chat endpoint path where text arrives unrendered, or passing {'text': [...messages...]} in a raw request with media attached.","solutions":["Pre-render your chat template client-side and pass the resulting string as input_text","Or use the endpoint/flow intended for this model so text reaches the processor as a str","If building requests programmatically, assert isinstance(text, str) before attaching media"],"exampleFix":"// before\ninput_text = [{\"role\": \"user\", \"content\": \"describe this\"}]\n// after\ninput_text = \"<|user|>\\ndescribe this<|end|>\"  # rendered string","handlingStrategy":"type-guard","validationCode":"assert isinstance(input_text, str) and input_text, 'render chat template to a string before attaching media'","typeGuard":"def is_rendered_prompt(text) -> bool:\n    return isinstance(text, str) and len(text) > 0","tryCatchPattern":null,"preventionTips":["Render chat templates client-side for this model","Never pass raw message lists when media is attached"],"tags":["multimodal","request-format","typeerror-contract","valueerror"],"backgroundTag":"invalid-request-payload","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}