deepset-ai/haystack · error · ValueError
{prompt_label} must render to exactly one {expected_role.val
Error message
{prompt_label} must render to exactly one {expected_role.value} message. Got {len(prompt_messages)} messages. What it means
Raised by _render_prompt_messages when the ChatPromptBuilder renders the prompt into zero or multiple messages instead of exactly one of the expected role. The Agent requires a single rendered message per prompt at execution setup time.
Source
Thrown at haystack/components/agents/utils.py:297
def _render_prompt_messages(
*, prompt_builder: ChatPromptBuilder, expected_role: ChatRole, prompt_label: str, kwargs: dict[str, Any]
) -> list[ChatMessage]:
"""
Render one Agent prompt and validate the rendered message.
:param prompt_builder: Builder configured with the prompt template.
:param expected_role: Role the rendered message must have.
:param prompt_label: Prompt name used in error messages.
:param kwargs: Runtime values available to the prompt template.
:returns: A single rendered prompt message.
:raises ValueError: If the prompt renders to zero, multiple, or wrong-role messages.
"""
prompt_kwargs = {var: kwargs[var] for var in prompt_builder.variables if var in kwargs}
prompt_messages = prompt_builder.run(**prompt_kwargs)["prompt"]
if len(prompt_messages) != 1:
raise ValueError(
f"{prompt_label} must render to exactly one {expected_role.value} message. "
f"Got {len(prompt_messages)} messages."
)
if not prompt_messages[0].is_from(expected_role):
raise ValueError(
f"{prompt_label} must render to a {expected_role.value} message. "
f"Got a message with role {prompt_messages[0].role}."
)
return prompt_messages
View on GitHub (pinned to e318778c9b)
Solutions
- Ensure the prompt template renders exactly one message block for all valid variable values.
- Inspect the template variables being passed in kwargs and simplify any that expand into several messages.
- Pre-render the prompt with the same variables using ChatPromptBuilder to verify output count before running the Agent.
Example fix
// before (template loops produce many messages)
prompt = "{% for q in queries %}{% message role='user' %}{{ q }}{% endmessage %}{% endfor %}"
// after
prompt = "{% message role='user' %}{{ queries|join('; ') }}{% endmessage %}" Defensive patterns
Strategy: validation
Validate before calling
from haystack.components.builders import ChatPromptBuilder
pb = ChatPromptBuilder(variables=list(vars_), template=[template_message])
out = pb.run(**kwargs)["prompt"]
assert len(out) == 1, f"prompt renders {len(out)} messages" Try / catch
try:
agent.run(query=q, **extra)
except ValueError as e:
if "must render to exactly one" in str(e):
logging.error("Prompt rendering issue: %s", e)
raise Prevention
- Pre-render prompts with the same kwargs in tests.
- Avoid templates that loop or branch into multiple messages.
- Pass only variables the prompt template declares.
When it happens
Trigger: Passing template variables (via run kwargs) that cause the prompt template to emit multiple message blocks, or a prompt whose Jinja template conditionally yields nothing/multiple messages.
Common situations: Template variables expanding into multiple messages; a custom prompt string with loops over messages; kwargs that change the rendered structure at runtime rather than init time.
Related errors
- user_prompt must define exactly one message block, found {le
- user_prompt message block must have role 'user', found role
- system_prompt must define exactly one message block, found {
- system_prompt message block must have role 'system', found r
- {prompt_label} must render to a {expected_role.value} messag
AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30).
Data as JSON: /api/errors/64ab869593ba6495.
Report an issue: GitHub.