langchain-ai/langchain · error · ChevronError

Trying to close tag "{tag_key}"\nLooks like it was not opene

Error message

Trying to close tag "{tag_key}"\nLooks like it was not opened.\nline {_CURRENT_LINE + 1}

What it means

Raised by the Mustache tokenizer in `langchain_core.utils.mustache` when a closing section tag `{{/name}}` appears but there is no currently open section to close (the stack of opened sections is empty). Mustache sections must be properly nested and closed; a close with no open is a structural error. The line number is one-based.

Source

Thrown at libs/core/langchain_core/utils/mustache.py:282

        # If we are a section tag
        elif tag_type in {"section", "inverted section"}:
            # Then open a new section
            open_sections.append(tag_key)
            _LAST_TAG_LINE = _CURRENT_LINE

        # If we are an end tag
        elif tag_type == "end":
            # Then check to see if the last opened section
            # is the same as us
            try:
                last_section = open_sections.pop()
            except IndexError as e:
                msg = (
                    f'Trying to close tag "{tag_key}"\n'
                    "Looks like it was not opened.\n"
                    f"line {_CURRENT_LINE + 1}"
                )
                raise ChevronError(msg) from e
            if tag_key != last_section:
                # Otherwise we need to complain
                msg = (
                    f'Trying to close tag "{tag_key}"\n'
                    f'last open tag is "{last_section}"\n'
                    f"line {_CURRENT_LINE + 1}"
                )
                raise ChevronError(msg)

        # Do the second check to see if we're a standalone
        is_standalone = r_sa_check(template, tag_type, is_standalone)

        # Which if we are
        if is_standalone:
            # Remove the stuff before the newline
            template = template.split("\n", 1)[-1]

            # Partials need to keep the spaces on their left

View on GitHub (pinned to e32fa9a52e)

Solutions

  1. Check the reported line and add the matching opening section tag `{{#name}}` above the content, or delete the stray closer.
  2. Make sure opener and closer names match exactly (case-sensitive).
  3. Lint templates with the tokenizer in CI or at startup so structural errors surface immediately.

Example fix

# before
template = "Answer: {{answer}} {{/details}}"

# after
template = "{{#details}}Answer: {{answer}}{{/details}}"
Defensive patterns

Strategy: validation

Validate before calling

import re

def sections_balanced(template: str) -> bool:
    stack = []
    for typ, key in re.findall(r"\{\{\s*(#|\^|/)\s*(.*?)\s*\}\}", template):
        if typ in "#^":
            stack.append(key)
        elif not stack or stack.pop() != key:
            return False
    return not stack

Try / catch

try:
    list(tokenize(template))
except ChevronError as e:
    raise ValueError(f"invalid template: {e}") from e

Prevention

When it happens

Trigger: A template containing `{{/items}}` with no preceding `{{#items}}` (or `{{^items}}`), rendered via `MustachePlaceholderFormatter.format` or parsed with `tokenize`. Also happens when the opening tag was itself malformed (e.g. typo `{{#tiems}}`) so it never registered as opened.

Common situations: Copy-paste editing of prompt templates that drops the opening tag; renaming a section in the opener but not the closer; closing tags left behind after deleting a conditional block; templates assembled by concatenation losing the opener.

Related errors


AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14). Data as JSON: /api/errors/f06da5638063beb7. Report an issue: GitHub.