deepset-ai/haystack · error

Invalid Jinja template '{template}': {e}

Error message

Invalid Jinja template '{template}': {e}

What it means

OutputAdapter validates its Jinja template at construction time by parsing it with the Jinja environment. A TemplateSyntaxError (e.g. unclosed {% if %}, bad filter syntax) is re-raised as a ValueError including the template and the underlying error, so misconfiguration fails fast before the pipeline runs.

Source

Thrown at haystack/components/converters/output_adapter.py:94

        self._unsafe = unsafe

        if self._unsafe:
            msg = (
                "Unsafe mode is enabled. This allows execution of arbitrary code in the Jinja template. "
                "Use this only if you trust the source of the template."
            )
            logger.warning(msg)
        self._env = (
            NativeEnvironment()
            if self._unsafe
            else HaystackSandboxedEnvironment(undefined=jinja2.runtime.StrictUndefined)
        )

        try:
            self._env.parse(template)  # Validate template syntax
            self.template = template
        except TemplateSyntaxError as e:
            raise ValueError(f"Invalid Jinja template '{template}': {e}") from e

        for name, filter_func in self.custom_filters.items():
            self._env.filters[name] = filter_func

        # b) extract variables in the template
        assigned_variables, template_variables = _extract_template_variables_and_assignments(
            env=self._env, template=self.template
        )
        route_input_names = template_variables - assigned_variables
        input_types.update(route_input_names)

        # the env is not needed, discarded automatically
        component.set_input_types(self, **dict.fromkeys(input_types, Any))
        component.set_output_types(self, output=output_type)
        self.output_type = output_type

    def run(self, **kwargs: Any) -> dict[str, Any]:
        """

View on GitHub (pinned to e318778c9b)

Solutions

  1. Fix the Jinja syntax reported in the message (check unclosed tags/brackets)
  2. Validate the template locally by parsing it with jinja2.Environment().parse(template)
  3. If the template is built dynamically, escape literal { as {{ and } as }}

Example fix

// before
OutputAdapter(template="{% if x %}{{ x }")  # unclosed tags
// after
OutputAdapter(template="{% if x %}{{ x }}{% endif %}")
Defensive patterns

Strategy: validation

Validate before calling

import jinja2
def validate_template(template: str) -> bool:
    try:
        jinja2.Environment().parse(template)
        return True
    except jinja2.TemplateSyntaxError:
        return False

Try / catch

try:
    adapter = OutputAdapter(template=t)
except ValueError as e:
    if "Invalid Jinja template" in str(e):
        report_template_syntax_error(t)
    else:
        raise

Prevention

When it happens

Trigger: OutputAdapter(template="...") with syntactically invalid Jinja: unbalanced {% %}/{{ }}, unknown block endings like {% endfor %} without {% for %}, malformed expressions.

Common situations: Hand-written templates with typos; f-string style braces pasted into Jinja; dynamically built templates where string interpolation broke the syntax.

Related errors


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