nodejs/node · error · TemplateSyntaxError

expected token %r, got %r

Error message

expected token %r, got %r

What it means

TokenStream.expect(expr) raised when the current token is not EOF but does not match the expected expression — the parser got a real token of the wrong kind. This is the non-EOF sibling of error 609 and indicates a structural syntax mistake rather than truncation.

Source

Thrown at tools/inspector_protocol/jinja2/lexer.py:381

    def close(self):
        """Close the stream."""
        self.current = Token(self.current.lineno, TOKEN_EOF, '')
        self._iter = None
        self.closed = True

    def expect(self, expr):
        """Expect a given token type and return it.  This accepts the same
        argument as :meth:`jinja2.lexer.Token.test`.
        """
        if not self.current.test(expr):
            expr = describe_token_expr(expr)
            if self.current.type is TOKEN_EOF:
                raise TemplateSyntaxError('unexpected end of template, '
                                          'expected %r.' % expr,
                                          self.current.lineno,
                                          self.name, self.filename)
            raise TemplateSyntaxError("expected token %r, got %r" %
                                      (expr, describe_token(self.current)),
                                      self.current.lineno,
                                      self.name, self.filename)
        try:
            return self.current
        finally:
            next(self)


def get_lexer(environment):
    """Return a lexer which is probably cached."""
    key = (environment.block_start_string,
           environment.block_end_string,
           environment.variable_start_string,
           environment.variable_end_string,
           environment.comment_start_string,
           environment.comment_end_string,
           environment.line_statement_prefix,

View on GitHub (pinned to 1b2de5e052)

Solutions

  1. Read the message: it states which token was expected and which was actually found at the given line.
  2. Fix the offending tag to supply the required token (e.g. add the condition expression after {% if %}).
  3. Cross-check the construct against Jinja2's tag grammar in the docs.

Example fix

{# before #}
{% if %}...{% endif %}

{# after #}
{% if user.is_admin %}...{% endif %}
Defensive patterns

Strategy: validation

Validate before calling

from jinja2 import Environment

def lint_template(source: str):
    env = Environment()
    env.parse(source)  # raises TemplateSyntaxError with line number on malformed input

Try / catch

from jinja2.exceptions import TemplateSyntaxError
try:
    env.parse(source)
except TemplateSyntaxError as e:
    log.error('template syntax at %s:%s: %s', name, e.lineno, e.message)

Prevention

When it happens

Trigger: Malformed tag such as {% if %}{% endif %} missing the condition, {% for in items %} missing the loop variable, stray operators, or any place the grammar required one token type but received another.

Common situations: Hand-editing a tag and dropping a required operand; using a tag outside its grammar (e.g. {% else %} without a matching {% if %}/{% for %}).

Related errors


AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13). Data as JSON: /api/errors/cde6a8680bd03324. Report an issue: GitHub.