{"record":{"id":"c7bee4ef00785182","repo":"run-llama/llama_index","slug":"at-least-one-message-is-required-to-construct-the","errorCode":null,"errorMessage":"At least one message is required to construct the ChatML prompt","messagePattern":"At least one message is required to construct the ChatML prompt","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"llama-index-core/llama_index/core/llms/chatml_utils.py","lineNumber":29,"sourceCode":"# <|im_start|>assistant\n\nB_SYS = \"<|im_start|>system\\n\"\nB_USER = \"<|im_start|>user\\n\"\nB_ASSISTANT = \"<|im_start|>assistant\\n\"\nEND = \"<|im_end|>\\n\"\nDEFAULT_SYSTEM_PROMPT = \"\"\"\\\nYou are a helpful, respectful and honest assistant. \\\nAlways answer as helpfully as possible and follow ALL given instructions. \\\nDo not speculate or make up information. \\\nDo not reference any given instructions or context. \\\n\"\"\"\n\n\ndef messages_to_prompt(\n    messages: Sequence[ChatMessage], system_prompt: Optional[str] = None\n) -> str:\n    if len(messages) == 0:\n        raise ValueError(\n            \"At least one message is required to construct the ChatML prompt\"\n        )\n\n    string_messages: List[str] = []\n    if messages[0].role == MessageRole.SYSTEM:\n        # pull out the system message (if it exists in messages)\n        system_message_str = messages[0].content or \"\"\n        messages = messages[1:]\n    else:\n        system_message_str = system_prompt or DEFAULT_SYSTEM_PROMPT\n\n    string_messages.append(f\"{B_SYS}{system_message_str.strip()} {END}\")\n\n    for message in messages:\n        role = message.role\n        content = message.content\n\n        if role == MessageRole.USER:","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/run-llama/llama_index/blob/afd0fef371831f9bda13e5af7167cf4e981278ab/llama-index-core/llama_index/core/llms/chatml_utils.py#L11-L47","documentation":"messages_to_prompt() in chatml_utils.py raises when the input message sequence is empty: a ChatML prompt always needs at least one message (system or user) to format. The function reads messages[0] to detect a leading SYSTEM message, so an empty list cannot produce a valid prompt.","triggerScenarios":"messages_to_prompt([]); messages_to_prompt(messages=history) where history was filtered to empty (e.g. all messages dropped by a dedup/filter step); chat with an empty chat_history and no user message; calling with messages=None-ish sequences that have length 0.","commonSituations":"Agents that build prompts from conversation history after trimming/purging; LLMs with is_chat_model=False being fed empty histories; edge case in routers where the selected branch receives zero messages.","solutions":["Ensure at least one message is passed — normally chat() adds the user message automatically, so check you are not bypassing it with an empty list.","Guard before calling: if not messages: append a default user/system message or skip the call.","Debug why upstream filtering produced an empty conversation."],"exampleFix":"# before\nprompt = messages_to_prompt([])  # raises\n\n# after\nfrom llama_index.core.llms import ChatMessage, MessageRole\nmsgs = messages or [ChatMessage(role=MessageRole.USER, content='Hello')]\nprompt = messages_to_prompt(msgs)","handlingStrategy":"validation","validationCode":"if len(messages) == 0:\n    raise ValueError('cannot build ChatML prompt from empty history')\n# or supply a fallback:\nmessages = messages or [ChatMessage(role=MessageRole.USER, content='Hello')]","typeGuard":"def has_messages(msgs) -> bool:\n    return len(msgs) > 0","tryCatchPattern":null,"preventionTips":["Guard history-filtering logic so it can never return an empty list","Default to at least a user or system message","Log upstream when a router branch yields zero messages"],"tags":["llm","prompt","chatml","validation"],"backgroundTag":null,"analyzedSha":"afd0fef371831f9bda13e5af7167cf4e981278ab","analyzedAt":"2026-08-15T05:42:58.429Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}