langchain-ai/langchain · error · ChevronError

unclosed set delimiter tag\nat line {_CURRENT_LINE}

Error message

unclosed set delimiter tag\nat line {_CURRENT_LINE}

What it means

Raised by the Mustache tokenizer in `langchain_core.utils.mustache` for a malformed set-delimiter tag. A tag starting with `=` (e.g. `{{= ... }}`) must end with `=` before the closing delimiter — `{{=<% %>=}}` — to switch delimiters. If the trailing `=` is missing, the tag is ambiguous and rejected. The message includes the line number.

Source

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

    tag_type = tag_types.get(tag[0], "variable")

    # If the type is not a variable
    if tag_type != "variable":
        # Then that first character is not needed
        tag = tag[1:]

    # If we might be a set delimiter tag
    if tag_type == "set delimiter?":
        # Double check to make sure we are
        if tag.endswith("="):
            tag_type = "set delimiter"
            # Remove the equal sign
            tag = tag[:-1]

        # Otherwise we should complain
        else:
            msg = f"unclosed set delimiter tag\nat line {_CURRENT_LINE}"
            raise ChevronError(msg)

    elif (
        # If we might be a no html escape tag
        tag_type == "no escape?"
        # And we have a third curly brace
        # (And are using curly braces as delimiters)
        and l_del == "{{"
        and r_del == "}}"
        and template.startswith("}")
    ):
        # Then we are a no html escape tag
        template = template[1:]
        tag_type = "no escape"

    # Strip the whitespace off the key and return
    return ((tag_type, tag.strip()), template)

View on GitHub (pinned to e32fa9a52e)

Solutions

  1. Fix the tag to the exact form `{{=<new> <new>=}}` (leading `=`, space-separated new delimiters, trailing `=`).
  2. If you did not intend to change delimiters, escape or remove the leading `=` inside the tag.
  3. Tokenize templates once at startup to catch delimiter errors early.

Example fix

# before
template = "{{=<% %>}}\nHi <%name%>"  # missing trailing '='

# after
template = "{{=<% %>=}}\nHi <%name%>"
Defensive patterns

Strategy: validation

Validate before calling

import re

def valid_set_delimiters(template: str) -> bool:
    # every set-delimiter tag must look like {{= X Y =}}
    for m in re.finditer(r"\{\{=[^}]*\}\}", template):
        if not re.fullmatch(r"\{\{=\s*\S+\s+\S+\s*=\}\}", m.group(0)):
            return False
    return True

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 `{{=<% %>}}` (forgot the closing `=`), or any tag whose first character is `=` but which does not end with `=`. Encountered when rendering via `MustachePlaceholderFormatter`/`tokenize`.

Common situations: Manually changing delimiters to embed literal `{{ }}` content (JSON, LaTeX) and mistyping the syntax; copying the set-delimiter idiom from docs with a typo; templates authored for a different Mustache dialect.

Related errors


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