run-llama/llama_index · error · ValueError
At least one message is required to construct the ChatML pro
Error message
At least one message is required to construct the ChatML prompt
What it means
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.
Source
Thrown at llama-index-core/llama_index/core/llms/chatml_utils.py:29
# <|im_start|>assistant
B_SYS = "<|im_start|>system\n"
B_USER = "<|im_start|>user\n"
B_ASSISTANT = "<|im_start|>assistant\n"
END = "<|im_end|>\n"
DEFAULT_SYSTEM_PROMPT = """\
You are a helpful, respectful and honest assistant. \
Always answer as helpfully as possible and follow ALL given instructions. \
Do not speculate or make up information. \
Do not reference any given instructions or context. \
"""
def messages_to_prompt(
messages: Sequence[ChatMessage], system_prompt: Optional[str] = None
) -> str:
if len(messages) == 0:
raise ValueError(
"At least one message is required to construct the ChatML prompt"
)
string_messages: List[str] = []
if messages[0].role == MessageRole.SYSTEM:
# pull out the system message (if it exists in messages)
system_message_str = messages[0].content or ""
messages = messages[1:]
else:
system_message_str = system_prompt or DEFAULT_SYSTEM_PROMPT
string_messages.append(f"{B_SYS}{system_message_str.strip()} {END}")
for message in messages:
role = message.role
content = message.content
if role == MessageRole.USER:View on GitHub (pinned to afd0fef371)
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.
Example fix
# before prompt = messages_to_prompt([]) # raises # after from llama_index.core.llms import ChatMessage, MessageRole msgs = messages or [ChatMessage(role=MessageRole.USER, content='Hello')] prompt = messages_to_prompt(msgs)
Defensive patterns
Strategy: validation
Validate before calling
if len(messages) == 0:
raise ValueError('cannot build ChatML prompt from empty history')
# or supply a fallback:
messages = messages or [ChatMessage(role=MessageRole.USER, content='Hello')] Type guard
def has_messages(msgs) -> bool:
return len(msgs) > 0 Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- query and response must be provided
- Must provide either prompt or prompt_template_str.
- Must provide either prompt or prompt_template_str.
- Must provide either template or selector.
- Max iterations of {max_iterations} reached! Either something
AI-assisted analysis of run-llama/llama_index@afd0fef371 (2026-08-15).
Data as JSON: /api/errors/c7bee4ef00785182.
Report an issue: GitHub.