deepset-ai/haystack · error · ValueError

{prompt_label} must render to a {expected_role.value} messag

Error message

{prompt_label} must render to a {expected_role.value} message. Got a message with role {prompt_messages[0].role}.

What it means

Raised when the prompt renders to exactly one message, but that message's role does not match the expected role for the prompt label (user or system). Caught at execution setup, after init-time static validation passed because the role was decided by template variables at render time.

Source

Thrown at haystack/components/agents/utils.py:302

    """
    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

  1. Fix the template so the rendered message role is hardcoded or constrained to the expected role ('user' for user_prompt, 'system' for system_prompt).
  2. Remove or correct any role variable passed via template kwargs.
  3. Add an explicit condition in the template raising for unexpected role values before rendering.

Example fix

// before
prompt = "{% message role=role %}{{ query }}{% endmessage %}"; agent.run(..., role="system")
// after
prompt = "{% message role='user' %}{{ query }}{% endmessage %}"
Defensive patterns

Strategy: validation

Validate before calling

out = prompt_builder.run(**kwargs)["prompt"]
assert len(out) == 1 and out[0].is_from(expected_role), f"got role {out[0].role if out else None}"

Try / catch

try:
    agent.run(**kwargs)
except ValueError as e:
    if "Got a message with role" in str(e):
        logging.error("Rendered prompt wrong role: %s", e)
    raise

Prevention

When it happens

Trigger: A template with a dynamic role (e.g. {% message role=role_var %}) where the runtime variable resolves to the wrong role for the prompt.

Common situations: Passing a role variable via run kwargs that overrides the expected role; mutating prompt template variables between init and run so the rendered role changes.

Related errors


AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30). Data as JSON: /api/errors/8343570fbba5215c. Report an issue: GitHub.