{"record":{"id":"57679c321284b073","repo":"deepset-ai/haystack","slug":"the-insert-tag-requires-an-expression-that-evalu","errorCode":null,"errorMessage":"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:] %}'.","messagePattern":"The 'insert' tag requires an expression that evaluates to a ChatMessage or a list of ChatMessage objects, for example '(.+?)' or '(.+?)'\\.","errorType":"validation","errorClass":"TemplateSyntaxError","httpStatus":null,"severity":"error","filePath":"haystack/utils/jinja2_chat_extension.py","lineNumber":158,"sourceCode":"    def _parse_insert_tag(self, parser: Any, lineno: int) -> nodes.Node:\n        \"\"\"\n        Parse the `{% insert %}` placeholder tag.\n\n        This bodyless tag evaluates an expression to a `ChatMessage` or a list of `ChatMessage` objects and expands\n        it into the same JSON-line format produced by `{% message %}` blocks, so messages provided at runtime can be\n        interleaved with literal message blocks (for example a system message above and a user message below).\n\n        The expression can be a plain variable (`{% insert messages %}`), a slice or index\n        (`{% insert messages[-1:] %}`, `{% insert messages[-1] %}`), or a combination of variables\n        (`{% insert previous + current %}`).\n\n        :param parser: The Jinja2 parser instance\n        :param lineno: The line number of the tag, used for error reporting.\n        :return: A CallBlock node that expands the evaluated expression.\n        :raises TemplateSyntaxError: If the tag is not given an expression.\n        \"\"\"\n        if parser.stream.current.test(\"block_end\"):\n            raise TemplateSyntaxError(\n                \"The 'insert' tag requires an expression that evaluates to a ChatMessage or a list of ChatMessage \"\n                \"objects, for example '{% insert messages %}' or '{% insert messages[-1:] %}'.\",\n                lineno,\n            )\n        expr = parser.parse_expression()\n        # Bodyless tag: empty body, no matching end tag required.\n        return nodes.CallBlock(\n            self.call_method(name=\"_build_inserted_messages_json\", args=[expr]), [], [], []\n        ).set_lineno(lineno)\n\n    def _parse_message_tag(self, parser: Any, lineno: int) -> nodes.Node | list[nodes.Node]:\n        \"\"\"\n        Parse the message tag and its attributes in the Jinja2 template.\n\n        This method handles the parsing of role (mandatory), name (optional), meta (optional) and message body content.\n\n        :param parser: The Jinja2 parser instance\n        :param lineno: The line number of the tag, used for error reporting.","sourceCodeStart":140,"sourceCodeEnd":176,"githubUrl":"https://github.com/deepset-ai/haystack/blob/e318778c9bf60a1963e3b5f451359655dd696c30/haystack/utils/jinja2_chat_extension.py#L140-L176","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","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"],"exampleFix":"// before\n{% insert %}\n// after\n{% insert messages[-1:] %}","handlingStrategy":"validation","validationCode":"import re\nassert re.search(r\"\\{%\\s*insert\\s+\\S+\\s*%\\}\", template), \"\\n{% insert %} requires an expression\"","typeGuard":"null","tryCatchPattern":"from jinja2.exceptions import TemplateSyntaxError\ntry:\n    tmpl = ChatPromptRenderEnv().from_string(template)\nexcept TemplateSyntaxError as e:\n    raise ValueError(f\"Invalid chat template near line {e.lineno}: {e.message}\") from e","preventionTips":["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"],"tags":["haystack","jinja2","template-syntax-error","insert-tag"],"backgroundTag":"template-syntax-error","analyzedSha":"e318778c9bf60a1963e3b5f451359655dd696c30","analyzedAt":"2026-08-30T11:45:20.711Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}