deepset-ai/haystack · error · TemplateSyntaxError
expected token 'assign'
Error message
expected token 'assign'
What it means
After reading the `role` name token, the parser calls expect("assign") requiring an = sign. Jinja2 raises TemplateSyntaxError("expected token 'assign'") when role is not followed by `=`, e.g. when a value or another attribute name appears instead.
Source
Thrown at haystack/utils/jinja2_chat_extension.py:183
return nodes.CallBlock(
self.call_method(name="_build_inserted_messages_json", args=[expr]), [], [], []
).set_lineno(lineno)
def _parse_message_tag(self, parser: Any, lineno: int) -> nodes.Node | list[nodes.Node]:
"""
Parse the message tag and its attributes in the Jinja2 template.
This method handles the parsing of role (mandatory), name (optional), meta (optional) and message body content.
:param parser: The Jinja2 parser instance
:param lineno: The line number of the tag, used for error reporting.
:return: A CallBlock node containing the parsed message configuration
:raises TemplateSyntaxError: If an invalid role is provided
"""
# Parse role attribute (mandatory)
parser.stream.expect("name:role")
parser.stream.expect("assign")
role_expr = parser.parse_expression()
if isinstance(role_expr, nodes.Const):
role = role_expr.value
if role not in self.SUPPORTED_ROLES:
raise TemplateSyntaxError(f"Role must be one of: {', '.join(self.SUPPORTED_ROLES)}", lineno)
# Parse optional name attribute
name_expr = None
if parser.stream.current.test("name:name"):
parser.stream.skip()
parser.stream.expect("assign")
name_expr = parser.parse_expression()
if not isinstance(name_expr.value, str):
raise TemplateSyntaxError("name must be a string", lineno)
# Parse optional meta attribute
meta_expr = NoneView on GitHub (pinned to e318778c9b)
Solutions
- Add the missing `=` after role: role="user"
- Quote the role value as a Python/Jinja string literal
- Validate the whole tag: {% message role="user" %}...{% endmessage %}
Example fix
// before
{% message role "user" %}Hi{% endmessage %}
// after
{% message role="user" %}Hi{% endmessage %} Defensive patterns
Strategy: validation
Validate before calling
import re
MSG_ROLE = re.compile(r"{%\s*message\s+role\s*=\s*['\"]\w+['\"]")
assert MSG_ROLE.search(template), "message tag needs role=\"...\"" Try / catch
try:
env.from_string(template)
except TemplateSyntaxError as e:
print(f"line {e.lineno}: {e.message}") Prevention
- Follow keyword-attribute syntax name=value exactly
- Quote the role value
- Run template compilation as part of unit tests
When it happens
Trigger: Writing {% message role "user" %} (missing =), or {% message role user %}, or a space/typo such as role-"user" in a ChatPromptBuilder template.
Common situations: Template syntax confusion from other templating engines; hand-editing templates and dropping the `=`.
Related errors
- expected token 'name:role'
- expected token 'assign', got ...
- Invalid Jinja template '{template}': {e}
- Document with ID '{doc.id}' comes from the PDF file '{resolv
- No `jq_schema` nor `content_key` specified. Set either or bo
AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30).
Data as JSON: /api/errors/a374cc6401be0ba2.
Report an issue: GitHub.