sgl-project/sglang · error · ValueError
The messages should be a list of dict.
Error message
The messages should be a list of dict.
What it means
generate_chat_conv expects request.messages to be a list of message objects (ChatCompletionMessage), not a plain string. If a str is passed, it raises this ValueError before iterating roles. This mirrors the OpenAI API where 'messages' is an array of dicts, not a string.
Source
Thrown at python/sglang/srt/parser/conversation.py:629
roles=conv.roles,
messages=list(conv.messages), # prevent in-place modification
offset=conv.offset,
sep_style=SeparatorStyle(conv.sep_style),
sep=conv.sep,
sep2=conv.sep2,
stop_str=conv.stop_str,
image_data=[],
video_data=[],
audio_data=[],
modalities=[],
image_token=conv.image_token,
audio_token=conv.audio_token,
video_token=conv.video_token,
image_token_at_prefix=conv.image_token_at_prefix,
)
if isinstance(request.messages, str):
raise ValueError("The messages should be a list of dict.")
for message in request.messages:
msg_role = message.role
if msg_role == "system":
if isinstance(message.content, str):
conv.system_message = message.content
elif isinstance(message.content, list):
if (
len(message.content) != 1
or getattr(message.content[0], "type", None) != "text"
):
raise ValueError("The system message should be a single text.")
else:
conv.system_message = getattr(message.content[0], "text", "")
elif msg_role == "user":
# Handle the various types of Chat Request content types here.
if isinstance(message.content, str):
conv.append_message(conv.roles[0], message.content)
else:View on GitHub (pinned to 0132848349)
Solutions
- Pass a list of message dicts: messages=[{"role":"user","content":"..."}]
- Use the completions API (text prompt) instead if you have a single string
Example fix
# before
llm.chat("Hello") # or messages="Hello"
# after
llm.chat([{"role":"user","content":"Hello"}]) Defensive patterns
Strategy: type-guard
Validate before calling
assert isinstance(messages, list) and all(isinstance(m, dict) for m in messages)
Type guard
def is_valid_messages(msgs) -> bool:
return isinstance(msgs, list) and all(
isinstance(m, dict) and m.get("role") in {"system","user","assistant"} for m in msgs
) Try / catch
try: resp = llm.chat(msgs) except ValueError as e: if "list of dict" in str(e): fix payload
Prevention
- Always build messages as a list of dicts
- Use the completions API for raw string prompts
When it happens
Trigger: Calling the chat completion path with GenerateChatReqInput(messages="Hello") instead of messages=[{"role":"user","content":"Hello"}].
Common situations: Treating the chat endpoint like the completions endpoint (which takes a string 'text'); quick scripts passing a raw string; LLM(... ) vs chat API confusion.
Related errors
- cache_dit_params must be a dict, got {type(raw).__name__}.
- Unknown cache_dit_params keys: {sorted(unknown)}. Valid keys
- cache_dit_params['secondary'] must be a dict, got {type(seco
- Unknown cache_dit_params['secondary'] keys: {sorted(unknown)
- runtime.response_format must be 'envelope' or 'raw'
AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28).
Data as JSON: /api/errors/be746aec03263e34.
Report an issue: GitHub.