deepset-ai/haystack · error · TemplateSyntaxError
expected token 'assign', got ...
Error message
expected token 'assign', got ...
What it means
The message tag's optional name= attribute is parsed only if the token `name` is present, and after `name` the parser expects an `=` (assign). Jinja2 raises TemplateSyntaxError("expected token 'assign', got ...") when `name` is not immediately followed by `=`. The got ... part shows the offending token.
Source
Thrown at haystack/utils/jinja2_chat_extension.py:195
: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 = None
if parser.stream.current.test("name:meta"):
parser.stream.skip()
parser.stream.expect("assign")
meta_expr = parser.parse_expression()
if not isinstance(meta_expr, nodes.Dict):
raise TemplateSyntaxError("meta must be a dictionary", lineno)
# Parse message body
body = parser.parse_statements(("name:endmessage",), drop_needle=True)
# Build message node with all parameters
return nodes.CallBlock(View on GitHub (pinned to e318778c9b)
Solutions
- Write name as a keyword attribute: name="greeting"
- Ensure a valid expression follows the `=` (a quoted string, since name must be a string)
- Remove the stray token between `name` and `=`
Example fix
// before
{% message role="user" name "greeting" %}Hi{% endmessage %}
// after
{% message role="user" name="greeting" %}Hi{% endmessage %} Defensive patterns
Strategy: validation
Validate before calling
import re assert re.search(r"\bname\s*=\s*['\"][^'\"]+['\"]", tag_src), "name must be name=\"...\""
Try / catch
try:
env.from_string(template)
except TemplateSyntaxError as e:
print(f"line {e.lineno}: {e.message}") Prevention
- Write optional attributes strictly as key=value pairs
- Ensure name values are quoted strings (they must be str)
- Test-render all prompt templates in CI
When it happens
Trigger: Writing {% message role="user" name "foo" %} or {% message role="user" name= %} (missing value) in a ChatPromptBuilder template.
Common situations: Typos while hand-writing templates; confusing positional arguments with keyword-style attributes.
Related errors
- expected token 'name:role'
- expected token 'assign'
- 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/054445ec767dd1c2.
Report an issue: GitHub.