{"record":{"id":"be746aec03263e34","repo":"sgl-project/sglang","slug":"the-messages-should-be-a-list-of-dict","errorCode":null,"errorMessage":"The messages should be a list of dict.","messagePattern":"The messages should be a list of dict\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/parser/conversation.py","lineNumber":629,"sourceCode":"        roles=conv.roles,\n        messages=list(conv.messages),  # prevent in-place modification\n        offset=conv.offset,\n        sep_style=SeparatorStyle(conv.sep_style),\n        sep=conv.sep,\n        sep2=conv.sep2,\n        stop_str=conv.stop_str,\n        image_data=[],\n        video_data=[],\n        audio_data=[],\n        modalities=[],\n        image_token=conv.image_token,\n        audio_token=conv.audio_token,\n        video_token=conv.video_token,\n        image_token_at_prefix=conv.image_token_at_prefix,\n    )\n\n    if isinstance(request.messages, str):\n        raise ValueError(\"The messages should be a list of dict.\")\n    for message in request.messages:\n        msg_role = message.role\n        if msg_role == \"system\":\n            if isinstance(message.content, str):\n                conv.system_message = 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(\"The system message should be a single text.\")\n                else:\n                    conv.system_message = getattr(message.content[0], \"text\", \"\")\n        elif msg_role == \"user\":\n            # Handle the various types of Chat Request content types here.\n            if isinstance(message.content, str):\n                conv.append_message(conv.roles[0], message.content)\n            else:","sourceCodeStart":611,"sourceCodeEnd":647,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/parser/conversation.py#L611-L647","documentation":"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.","triggerScenarios":"Calling the chat completion path with GenerateChatReqInput(messages=\"Hello\") instead of messages=[{\"role\":\"user\",\"content\":\"Hello\"}].","commonSituations":"Treating the chat endpoint like the completions endpoint (which takes a string 'text'); quick scripts passing a raw string; LLM(... ) vs chat API confusion.","solutions":["Pass a list of message dicts: messages=[{\"role\":\"user\",\"content\":\"...\"}]","Use the completions API (text prompt) instead if you have a single string"],"exampleFix":"# before\nllm.chat(\"Hello\")  # or messages=\"Hello\"\n# after\nllm.chat([{\"role\":\"user\",\"content\":\"Hello\"}])","handlingStrategy":"type-guard","validationCode":"assert isinstance(messages, list) and all(isinstance(m, dict) for m in messages)","typeGuard":"def is_valid_messages(msgs) -> bool:\n    return isinstance(msgs, list) and all(\n        isinstance(m, dict) and m.get(\"role\") in {\"system\",\"user\",\"assistant\"} for m in msgs\n    )","tryCatchPattern":"try: resp = llm.chat(msgs)\nexcept ValueError as e: if \"list of dict\" in str(e): fix payload","preventionTips":["Always build messages as a list of dicts","Use the completions API for raw string prompts"],"tags":["chat-api","request-validation","messages"],"backgroundTag":"invalid-request-payload","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}