{"record":{"id":"e18551e65ed8dcb3","repo":"sgl-project/sglang","slug":"the-assistant-s-response-should-be-a-single-text","errorCode":null,"errorMessage":"The assistant's response should be a single text.","messagePattern":"The assistant's response should be a single text\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/parser/conversation.py","lineNumber":702,"sourceCode":"                        conv.append_video(content.video_url.url)\n                    elif content.type == \"audio_url\":\n                        real_content += audio_token\n                        conv.append_audio(content.audio_url.url)\n                if add_token_as_needed:\n                    real_content = _get_full_multimodal_text_prompt(\n                        conv.image_token, num_image_url, real_content\n                    )\n                conv.append_message(conv.roles[0], real_content)\n        elif msg_role == \"assistant\":\n            parsed_content = \"\"\n            if isinstance(message.content, str):\n                parsed_content = message.content\n            elif isinstance(message.content, list):\n                if (\n                    len(message.content) != 1\n                    or getattr(message.content[0], \"type\", None) != \"text\"\n                ):\n                    raise ValueError(\n                        \"The assistant's response should be a single text.\"\n                    )\n                else:\n                    parsed_content = getattr(message.content[0], \"text\", \"\")\n            conv.append_message(conv.roles[1], parsed_content)\n        else:\n            raise ValueError(f\"Unknown role: {msg_role}\")\n\n    # Add a blank message for the assistant.\n    conv.append_message(conv.roles[1], None)\n    return conv\n\n\n# llama2 template\n# reference: https://github.com/lm-sys/FastChat/blob/main/fastchat/conversation.py\n# reference: https://github.com/facebookresearch/llama/blob/1a240688810f8036049e8da36b073f63d2ac552c/llama/generation.py#L212\nregister_conv_template(\n    Conversation(","sourceCodeStart":684,"sourceCodeEnd":720,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/parser/conversation.py#L684-L720","documentation":"Assistant messages in the history with list content must contain exactly one text part. This validates prior assistant turns when replaying conversation history in generate_chat_conv; multimodal or multi-part assistant content is rejected.","triggerScenarios":"Passing a prior assistant message with content=[{\"type\":\"image_url\",...}] or multiple parts in a multi-turn chat request.","commonSituations":"Replaying recorded conversations where an assistant turn was (incorrectly) stored with parts, or clients that uniformly structure all message contents as lists.","solutions":["Store/replay prior assistant messages as plain strings","If a list is used, ensure it has exactly one {\"type\":\"text\",...} part","Strip non-text parts from historical assistant messages before sending"],"exampleFix":"# before\n{\"role\":\"assistant\",\"content\":[{\"type\":\"text\",\"text\":\"Hi\"},{\"type\":\"text\",\"text\":\"there\"}]}\n# after\n{\"role\":\"assistant\",\"content\":\"Hi there\"}","handlingStrategy":"type-guard","validationCode":"for m in messages:\n    if m[\"role\"] == \"assistant\" and isinstance(m[\"content\"], list):\n        assert len(m[\"content\"]) == 1 and m[\"content\"][0].get(\"type\") == \"text\"","typeGuard":"def ok_assistant(c): return isinstance(c, str) or (isinstance(c, list) and len(c)==1 and c[0].get(\"type\")==\"text\")","tryCatchPattern":null,"preventionTips":["Store historical assistant turns as strings","Sanitize recorded conversations before replay"],"tags":["chat-api","assistant-message","validation"],"backgroundTag":"invalid-request-payload","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}