sgl-project/sglang · error · ValueError

The assistant's response should be a single text.

Error message

The assistant's response should be a single text.

What it means

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.

Source

Thrown at python/sglang/srt/parser/conversation.py:702

                        conv.append_video(content.video_url.url)
                    elif content.type == "audio_url":
                        real_content += audio_token
                        conv.append_audio(content.audio_url.url)
                if add_token_as_needed:
                    real_content = _get_full_multimodal_text_prompt(
                        conv.image_token, num_image_url, real_content
                    )
                conv.append_message(conv.roles[0], real_content)
        elif msg_role == "assistant":
            parsed_content = ""
            if isinstance(message.content, str):
                parsed_content = message.content
            elif isinstance(message.content, list):
                if (
                    len(message.content) != 1
                    or getattr(message.content[0], "type", None) != "text"
                ):
                    raise ValueError(
                        "The assistant's response should be a single text."
                    )
                else:
                    parsed_content = getattr(message.content[0], "text", "")
            conv.append_message(conv.roles[1], parsed_content)
        else:
            raise ValueError(f"Unknown role: {msg_role}")

    # Add a blank message for the assistant.
    conv.append_message(conv.roles[1], None)
    return conv


# llama2 template
# reference: https://github.com/lm-sys/FastChat/blob/main/fastchat/conversation.py
# reference: https://github.com/facebookresearch/llama/blob/1a240688810f8036049e8da36b073f63d2ac552c/llama/generation.py#L212
register_conv_template(
    Conversation(

View on GitHub (pinned to 0132848349)

Solutions

  1. Store/replay prior assistant messages as plain strings
  2. If a list is used, ensure it has exactly one {"type":"text",...} part
  3. Strip non-text parts from historical assistant messages before sending

Example fix

# before
{"role":"assistant","content":[{"type":"text","text":"Hi"},{"type":"text","text":"there"}]}
# after
{"role":"assistant","content":"Hi there"}
Defensive patterns

Strategy: type-guard

Validate before calling

for m in messages:
    if m["role"] == "assistant" and isinstance(m["content"], list):
        assert len(m["content"]) == 1 and m["content"][0].get("type") == "text"

Type guard

def ok_assistant(c): return isinstance(c, str) or (isinstance(c, list) and len(c)==1 and c[0].get("type")=="text")

Prevention

When it happens

Trigger: Passing a prior assistant message with content=[{"type":"image_url",...}] or multiple parts in a multi-turn chat request.

Common situations: Replaying recorded conversations where an assistant turn was (incorrectly) stored with parts, or clients that uniformly structure all message contents as lists.

Related errors


AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28). Data as JSON: /api/errors/e18551e65ed8dcb3. Report an issue: GitHub.