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

  1. Write name as a keyword attribute: name="greeting"
  2. Ensure a valid expression follows the `=` (a quoted string, since name must be a string)
  3. 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

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


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