deepset-ai/haystack · error · TemplateSyntaxError

The 'insert' tag requires an expression that evaluates to a

Error message

The 'insert' tag requires an expression that evaluates to a ChatMessage or a list of ChatMessage objects, for example '{% insert messages %}' or '{% insert messages[-1:] %}'.

What it means

TemplateSyntaxError raised by the InsertTag's `_parse_insert_tag` in Haystack's Jinja2 chat extension when the {% insert %} tag has no expression before the block end. The tag must evaluate to a ChatMessage or a list of ChatMessage objects to splice into the template output.

Source

Thrown at haystack/utils/jinja2_chat_extension.py:158

    def _parse_insert_tag(self, parser: Any, lineno: int) -> nodes.Node:
        """
        Parse the `{% insert %}` placeholder tag.

        This bodyless tag evaluates an expression to a `ChatMessage` or a list of `ChatMessage` objects and expands
        it into the same JSON-line format produced by `{% message %}` blocks, so messages provided at runtime can be
        interleaved with literal message blocks (for example a system message above and a user message below).

        The expression can be a plain variable (`{% insert messages %}`), a slice or index
        (`{% insert messages[-1:] %}`, `{% insert messages[-1] %}`), or a combination of variables
        (`{% insert previous + current %}`).

        :param parser: The Jinja2 parser instance
        :param lineno: The line number of the tag, used for error reporting.
        :return: A CallBlock node that expands the evaluated expression.
        :raises TemplateSyntaxError: If the tag is not given an expression.
        """
        if parser.stream.current.test("block_end"):
            raise TemplateSyntaxError(
                "The 'insert' tag requires an expression that evaluates to a ChatMessage or a list of ChatMessage "
                "objects, for example '{% insert messages %}' or '{% insert messages[-1:] %}'.",
                lineno,
            )
        expr = parser.parse_expression()
        # Bodyless tag: empty body, no matching end tag required.
        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.

View on GitHub (pinned to e318778c9b)

Solutions

  1. Provide an expression after the tag: {% insert messages %} or {% insert messages[-1:] %}
  2. Ensure the referenced variable is defined in the template context and holds a ChatMessage or list of ChatMessage
  3. Check for accidental deletion of the expression when editing the template

Example fix

// before
{% insert %}
// after
{% insert messages[-1:] %}
Defensive patterns

Strategy: validation

Validate before calling

import re
assert re.search(r"\{%\s*insert\s+\S+\s*%\}", template), "\n{% insert %} requires an expression"

Type guard

null

Try / catch

from jinja2.exceptions import TemplateSyntaxError
try:
    tmpl = ChatPromptRenderEnv().from_string(template)
except TemplateSyntaxError as e:
    raise ValueError(f"Invalid chat template near line {e.lineno}: {e.message}") from e

Prevention

When it happens

Trigger: Writing a template with a bare tag like `{% insert %}` or `{% insert %}...{% endinsert %}` with nothing after the tag name, causing the parser to hit block_end immediately while expecting an expression.

Common situations: Copy-pasting template fragments and losing the variable name; commenting out a variable while leaving the tag; typos that make the expression parse as nothing (e.g. `{% insert %}` followed by newline in a bodyless usage).

Related errors


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