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
- Provide an expression after the tag: {% insert messages %} or {% insert messages[-1:] %}
- Ensure the referenced variable is defined in the template context and holds a ChatMessage or list of ChatMessage
- 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
- Always follow {% insert %} with an expression that is a ChatMessage or list of ChatMessages
- Test templates with a render smoke test before deploying
- Validate template variables exist in the render context
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
- Role must be one of: {', '.join(self.SUPPORTED_ROLES)}
- name must be a string
- meta must be a dictionary
- Message template produced content that couldn't be parsed in
- expected token 'name:role'
AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30).
Data as JSON: /api/errors/57679c321284b073.
Report an issue: GitHub.