{"record":{"id":"64ab869593ba6495","repo":"deepset-ai/haystack","slug":"prompt-label-must-render-to-exactly-one-expecte","errorCode":null,"errorMessage":"{prompt_label} must render to exactly one {expected_role.value} message. Got {len(prompt_messages)} messages.","messagePattern":"(.+?) must render to exactly one (.+?) message\\. Got (.+?) messages\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"haystack/components/agents/utils.py","lineNumber":297,"sourceCode":"\n\ndef _render_prompt_messages(\n    *, prompt_builder: ChatPromptBuilder, expected_role: ChatRole, prompt_label: str, kwargs: dict[str, Any]\n) -> list[ChatMessage]:\n    \"\"\"\n    Render one Agent prompt and validate the rendered message.\n\n    :param prompt_builder: Builder configured with the prompt template.\n    :param expected_role: Role the rendered message must have.\n    :param prompt_label: Prompt name used in error messages.\n    :param kwargs: Runtime values available to the prompt template.\n    :returns: A single rendered prompt message.\n    :raises ValueError: If the prompt renders to zero, multiple, or wrong-role messages.\n    \"\"\"\n    prompt_kwargs = {var: kwargs[var] for var in prompt_builder.variables if var in kwargs}\n    prompt_messages = prompt_builder.run(**prompt_kwargs)[\"prompt\"]\n    if len(prompt_messages) != 1:\n        raise ValueError(\n            f\"{prompt_label} must render to exactly one {expected_role.value} message. \"\n            f\"Got {len(prompt_messages)} messages.\"\n        )\n    if not prompt_messages[0].is_from(expected_role):\n        raise ValueError(\n            f\"{prompt_label} must render to a {expected_role.value} message. \"\n            f\"Got a message with role {prompt_messages[0].role}.\"\n        )\n    return prompt_messages\n","sourceCodeStart":279,"sourceCodeEnd":307,"githubUrl":"https://github.com/deepset-ai/haystack/blob/e318778c9bf60a1963e3b5f451359655dd696c30/haystack/components/agents/utils.py#L279-L307","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before (template loops produce many messages)\nprompt = \"{% for q in queries %}{% message role='user' %}{{ q }}{% endmessage %}{% endfor %}\"\n// after\nprompt = \"{% message role='user' %}{{ queries|join('; ') }}{% endmessage %}\"","handlingStrategy":"validation","validationCode":"from haystack.components.builders import ChatPromptBuilder\npb = ChatPromptBuilder(variables=list(vars_), template=[template_message])\nout = pb.run(**kwargs)[\"prompt\"]\nassert len(out) == 1, f\"prompt renders {len(out)} messages\"","typeGuard":null,"tryCatchPattern":"try:\n    agent.run(query=q, **extra)\nexcept ValueError as e:\n    if \"must render to exactly one\" in str(e):\n        logging.error(\"Prompt rendering issue: %s\", e)\n    raise","preventionTips":["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."],"tags":["haystack","agents","prompt","rendering"],"backgroundTag":"prompt-render-count-mismatch","analyzedSha":"e318778c9bf60a1963e3b5f451359655dd696c30","analyzedAt":"2026-08-30T11:45:20.711Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}