{"record":{"id":"3f4c0fda07a297be","repo":"sgl-project/sglang","slug":"cosmos3-prompt-batch-must-not-be-empty","errorCode":null,"errorMessage":"Cosmos3 prompt batch must not be empty","messagePattern":"Cosmos3 prompt batch must not be empty","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/multimodal_gen/runtime/pipelines_core/stages/model_specific_stages/cosmos3.py","lineNumber":301,"sourceCode":"        result = VerificationResult()\n        result.add_check(\"prompt\", batch.prompt, V.string_or_list_strings)\n        return result\n\n    def _tokenize_prompt(\n        self,\n        text: str | list[str],\n        max_sequence_length: int,\n        device: torch.device,\n        use_system_prompt: bool = False,\n        system_prompt: str | None = None,\n    ) -> tuple[torch.Tensor, torch.Tensor, int]:\n        \"\"\"Tokenize a prompt using Qwen2 chat template.\n\n        Returns (input_ids, attention_mask, seq_len) as [B, S] tensors.\n        \"\"\"\n        texts = text if isinstance(text, (list, tuple)) else [text]\n        if not texts:\n            raise ValueError(\"Cosmos3 prompt batch must not be empty\")\n        input_id_lists: list[list[int]] = []\n        attention_mask_lists: list[list[int]] = []\n        seq_lens: list[int] = []\n        pad_token_id = self.tokenizer.pad_token_id or 0\n        vision_start_id = self.tokenizer.convert_tokens_to_ids(\"<|vision_start|>\")\n        for text_item in texts:\n            conversations = []\n            if use_system_prompt:\n                conversations.append(\n                    {\n                        \"role\": \"system\",\n                        \"content\": system_prompt or COSMOS3_VIDEO_SYSTEM_PROMPT,\n                    }\n                )\n            conversations.append({\"role\": \"user\", \"content\": text_item})\n\n            result = self.tokenizer.apply_chat_template(\n                conversations,","sourceCodeStart":283,"sourceCodeEnd":319,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/multimodal_gen/runtime/pipelines_core/stages/model_specific_stages/cosmos3.py#L283-L319","documentation":"_tokenize_prompt normalizes its input to a list of texts and requires at least one entry. An empty list (or empty tuple) means there are no prompts to tokenize, so the stage raises instead of producing an empty batch.","triggerScenarios":"Calling the pipeline/stage with prompt=[] (or the tokenization helper directly with an empty list) — e.g. a batching layer that flushed an empty micro-batch, or upstream filtering removed all prompts.","commonSituations":"Dynamic batching where a filter (safety, length) removes every prompt; a UI submitting an empty prompt list; tests iterating over an empty dataset.","solutions":["Skip the call entirely when the prompt list is empty (guard at the caller)","Ensure upstream filtering/dequeuing never forwards an empty batch downstream","Pass at least one prompt string"],"exampleFix":"# before\nids, mask, lens = stage._tokenize_prompt([], tokenizer_max_length)\n# after\nif not prompts:\n    return  # or continue\nids, mask, lens = stage._tokenize_prompt(prompts, tokenizer_max_length)","handlingStrategy":"validation","validationCode":"prompts = list(prompts) if isinstance(prompts, (list, tuple)) else [prompts]\nif not prompts:\n    return  # skip empty batch","typeGuard":"def nonempty_prompt_batch(text) -> bool:\n    texts = list(text) if isinstance(text, (list, tuple)) else [text]\n    return len(texts) > 0","tryCatchPattern":null,"preventionTips":["Guard batching layers against flushing empty micro-batches"],"tags":["cosmos3","tokenization","empty-prompt","empty-batch"],"backgroundTag":"empty-input-list","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}