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

  1. 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.
  2. Guard before calling: if not messages: append a default user/system message or skip the call.
  3. 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

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


AI-assisted analysis of run-llama/llama_index@afd0fef371 (2026-08-15). Data as JSON: /api/errors/c7bee4ef00785182. Report an issue: GitHub.