{"record":{"id":"59a7ac5a6b193323","repo":"nodejs/node","slug":"unexpected-s-expected-s","errorCode":null,"errorMessage":"unexpected '%s', expected '%s'","messagePattern":"unexpected '(.+?)', expected '(.+?)'","errorType":"exception","errorClass":"TemplateSyntaxError","httpStatus":null,"severity":"error","filePath":"tools/inspector_protocol/jinja2/lexer.py","lineNumber":686,"sourceCode":"                # strings as token just are yielded as it.\n                else:\n                    data = m.group()\n                    # update brace/parentheses balance\n                    if tokens == 'operator':\n                        if data == '{':\n                            balancing_stack.append('}')\n                        elif data == '(':\n                            balancing_stack.append(')')\n                        elif data == '[':\n                            balancing_stack.append(']')\n                        elif data in ('}', ')', ']'):\n                            if not balancing_stack:\n                                raise TemplateSyntaxError('unexpected \\'%s\\'' %\n                                                          data, lineno, name,\n                                                          filename)\n                            expected_op = balancing_stack.pop()\n                            if expected_op != data:\n                                raise TemplateSyntaxError('unexpected \\'%s\\', '\n                                                          'expected \\'%s\\'' %\n                                                          (data, expected_op),\n                                                          lineno, name,\n                                                          filename)\n                    # yield items\n                    if data or tokens not in ignore_if_empty:\n                        yield lineno, tokens, data\n                    lineno += data.count('\\n')\n\n                # fetch new position into new variable so that we can check\n                # if there is a internal parsing error which would result\n                # in an infinite loop\n                pos2 = m.end()\n\n                # handle state changes\n                if new_state is not None:\n                    # remove the uppermost state\n                    if new_state == '#pop':","sourceCodeStart":668,"sourceCodeEnd":704,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/tools/inspector_protocol/jinja2/lexer.py#L668-L704","documentation":"Sibling of 612: a closing bracket }, ), or ] was found and the stack was non-empty, but the expected opener (top of balancing_stack) did not match — e.g. opened with '[' but closed with ')'. The lexer reports both the actual and the expected bracket.","triggerScenarios":"Mismatched bracket pairs such as {{ foo[bar) }}, {{ func(x] }}, or {{ dict('k': v) }} confusing ( with [.","commonSituations":"Mixing parentheses, brackets, and braces when nesting calls/subscripts/literals; refactor typos.","solutions":["Read both symbols in the message: it tells you which closer was found and which was expected.","Replace the wrong closer with the matching one for the innermost opener."],"exampleFix":"{# before #}\n{{ items[0) }}\n\n{# after #}\n{{ items[0] }}","handlingStrategy":"validation","validationCode":"def brackets_match(expr: str) -> bool:\n    pairs = {')': '(', ']': '[', '}': '{'}\n    stack = []\n    for ch in expr:\n        if ch in '([{':\n            stack.append(ch)\n        elif ch in pairs:\n            if not stack:\n                return False\n            if stack.pop() != pairs[ch]:\n                return False\n    return not stack","typeGuard":null,"tryCatchPattern":"from jinja2.exceptions import TemplateSyntaxError\ntry:\n    env.parse(source)\nexcept TemplateSyntaxError as e:\n    log.error('mismatched bracket at %s:%s: %s', name, e.lineno, e.message)","preventionTips":["Match each closer to the innermost opener of the same kind.","Validate templates with env.parse in CI.","Avoid nesting different bracket types densely; refactor long expressions."],"tags":["jinja2","syntax","lexer","mismatched-brackets"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}