{"record":{"id":"dd5d801a81650f0d","repo":"nodejs/node","slug":"unexpected-end-of-template-expected-r","errorCode":null,"errorMessage":"unexpected end of template, expected %r.","messagePattern":"unexpected end of template, expected %r\\.","errorType":"exception","errorClass":"TemplateSyntaxError","httpStatus":null,"severity":"error","filePath":"tools/inspector_protocol/jinja2/lexer.py","lineNumber":377,"sourceCode":"                self.current = next(self._iter)\n            except StopIteration:\n                self.close()\n        return rv\n\n    def close(self):\n        \"\"\"Close the stream.\"\"\"\n        self.current = Token(self.current.lineno, TOKEN_EOF, '')\n        self._iter = None\n        self.closed = True\n\n    def expect(self, expr):\n        \"\"\"Expect a given token type and return it.  This accepts the same\n        argument as :meth:`jinja2.lexer.Token.test`.\n        \"\"\"\n        if not self.current.test(expr):\n            expr = describe_token_expr(expr)\n            if self.current.type is TOKEN_EOF:\n                raise TemplateSyntaxError('unexpected end of template, '\n                                          'expected %r.' % expr,\n                                          self.current.lineno,\n                                          self.name, self.filename)\n            raise TemplateSyntaxError(\"expected token %r, got %r\" %\n                                      (expr, describe_token(self.current)),\n                                      self.current.lineno,\n                                      self.name, self.filename)\n        try:\n            return self.current\n        finally:\n            next(self)\n\n\ndef get_lexer(environment):\n    \"\"\"Return a lexer which is probably cached.\"\"\"\n    key = (environment.block_start_string,\n           environment.block_end_string,\n           environment.variable_start_string,","sourceCodeStart":359,"sourceCodeEnd":395,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/tools/inspector_protocol/jinja2/lexer.py#L359-L395","documentation":"TokenStream.expect(expr) asserts the current token matches an expected expression. When the current token is EOF (TOKEN_EOF) instead, the parser had run out of input while still expecting more — typically an unclosed block or expression. Jinja2 surfaces this as 'unexpected end of template, expected <expr>'.","triggerScenarios":"An unclosed {% if %}/{% for %}/{% block %}/{% macro %} (missing {% endif %} etc.), an unterminated {{ ... }} expression, or an unclosed ( / [ / { inside an expression that runs to the end of the source.","commonSituations":"Forgetting the closing tag after editing a template; truncating a template during partial load; copy-paste that drops the closing block tag.","solutions":["Locate the unclosed construct: the error line number points at EOF where the parser expected the closing token.","Add the missing {% endif %}, {% endfor %}, {% endblock %}, or {% endmacro %} matching the most recent opening tag.","Close any open ( [ { in expressions and any unterminated {{ }} / {% %} tag.","Use a linting/editor plugin that highlights unclosed Jinja2 blocks."],"exampleFix":"{# before #}\n{% if user.active %}\n  Hello {{ user.name }}\n{# EOF reached, no endif #}\n\n{# after #}\n{% if user.active %}\n  Hello {{ user.name }}\n{% endif %}","handlingStrategy":"validation","validationCode":"from jinja2 import Environment\n\ndef check_template_balanced(source: str) -> bool:\n    env = Environment()\n    try:\n        env.parse(source)\n        return True\n    except Exception:\n        return False","typeGuard":null,"tryCatchPattern":"from jinja2.exceptions import TemplateSyntaxError\ntry:\n    tmpl = env.get_template(name)\nexcept TemplateSyntaxError as e:\n    if 'unexpected end of template' in str(e):\n        report(f'{name}: unclosed block near line {e.lineno}')\n    raise","preventionTips":["Validate templates with env.parse(source) at load/test time.","Use an editor with Jinja2 bracket/tag matching.","Keep blocks small and close tags immediately after opening them."],"tags":["jinja2","syntax","parser","unclosed-block"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}