{"record":{"id":"cf28bd5d4262afa0","repo":"langchain-ai/langchain","slug":"trying-to-close-tag-tag-key-nlast-open-tag-is","errorCode":null,"errorMessage":"Trying to close tag \"{tag_key}\"\\nlast open tag is \"{last_section}\"\\nline {_CURRENT_LINE + 1}","messagePattern":"Trying to close tag \"(.+?)\"\\\\nlast open tag is \"(.+?)\"\\\\nline (.+?)","errorType":"exception","errorClass":"ChevronError","httpStatus":null,"severity":"error","filePath":"libs/core/langchain_core/utils/mustache.py","lineNumber":290,"sourceCode":"            # Then check to see if the last opened section\n            # is the same as us\n            try:\n                last_section = open_sections.pop()\n            except IndexError as e:\n                msg = (\n                    f'Trying to close tag \"{tag_key}\"\\n'\n                    \"Looks like it was not opened.\\n\"\n                    f\"line {_CURRENT_LINE + 1}\"\n                )\n                raise ChevronError(msg) from e\n            if tag_key != last_section:\n                # Otherwise we need to complain\n                msg = (\n                    f'Trying to close tag \"{tag_key}\"\\n'\n                    f'last open tag is \"{last_section}\"\\n'\n                    f\"line {_CURRENT_LINE + 1}\"\n                )\n                raise ChevronError(msg)\n\n        # Do the second check to see if we're a standalone\n        is_standalone = r_sa_check(template, tag_type, is_standalone)\n\n        # Which if we are\n        if is_standalone:\n            # Remove the stuff before the newline\n            template = template.split(\"\\n\", 1)[-1]\n\n            # Partials need to keep the spaces on their left\n            if tag_type != \"partial\":\n                # But other tags don't\n                literal = literal.rstrip(\" \")\n\n        # Start yielding\n        # Ignore literals that are empty\n        if literal:\n            yield (\"literal\", literal)","sourceCodeStart":272,"sourceCodeEnd":308,"githubUrl":"https://github.com/langchain-ai/langchain/blob/e32fa9a52eab3b61ad7a45399bfde59b3e580fc4/libs/core/langchain_core/utils/mustache.py#L272-L308","documentation":"Raised by the Mustache tokenizer in `langchain_core.utils.mustache` when a closing section tag `{{/name}}` does not match the most recently opened section. Mustache requires properly nested sections (LIFO), so `{{#a}}...{{/b}}` is rejected; the message names both the tag being closed and the actually-open section. Line numbers are one-based.","triggerScenarios":"Interleaved/nested sections closed out of order, e.g. `{{#a}}{{#b}}...{{/a}}{{/b}}`, rendered via `MustachePlaceholderFormatter` or `tokenize`; or opener/closer names that differ by a typo or whitespace.","commonSituations":"Hand-nested loops/conditionals in prompt templates closed in the wrong order; renaming one of two similar sections (`{{#tool}}` vs `{{#tools}}`) and updating only one side; merging template fragments that break nesting.","solutions":["Reorder the closing tags so they mirror the opening order exactly (innermost closes first).","Verify exact name matches between `{{#name}}`/`{{^name}}` openers and `{{/name}}` closers — the message tells you the expected name.","Auto-format/lint Mustache templates in CI to enforce balanced nesting."],"exampleFix":"# before\ntemplate = \"{{#a}}A{{#b}}B{{/a}}{{/b}}\"  # closes 'a' while 'b' is open\n\n# after\ntemplate = \"{{#a}}A{{#b}}B{{/b}}{{/a}}\"","handlingStrategy":"validation","validationCode":"import re\n\ndef sections_balanced(template: str) -> bool:\n    stack = []\n    for typ, key in re.findall(r\"\\{\\{\\s*(#|\\^|/)\\s*(.*?)\\s*\\}\\}\", template):\n        if typ in \"#^\":\n            stack.append(key)\n        elif not stack or stack.pop() != key:\n            return False\n    return not stack\n\nif not sections_balanced(template):\n    raise ValueError(\"unbalanced mustache sections\")","typeGuard":null,"tryCatchPattern":"try:\n    list(tokenize(template))\nexcept ChevronError as e:\n    # message names the tag and the actually-open section\n    raise ValueError(f\"invalid template: {e}\") from e","preventionTips":["Use the error message: 'last open tag is X' tells you the exact expected closer.","Avoid hand-nesting deeply; extract partials instead.","Balance-check templates in CI."],"tags":["mustache","sections","nesting"],"backgroundTag":null,"analyzedSha":"e32fa9a52eab3b61ad7a45399bfde59b3e580fc4","analyzedAt":"2026-08-14T18:42:09.092Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}