{"record":{"id":"069bf0623ac36fa6","repo":"langchain-ai/langchain","slug":"unclosed-tag-at-line-current-line","errorCode":null,"errorMessage":"unclosed tag at line {_CURRENT_LINE}","messagePattern":"unclosed tag at line (.+?)","errorType":"exception","errorClass":"ChevronError","httpStatus":null,"severity":"error","filePath":"libs/core/langchain_core/utils/mustache.py","lineNumber":149,"sourceCode":"        ChevronError: If the set delimiter tag is unclosed.\n    \"\"\"\n    tag_types = {\n        \"!\": \"comment\",\n        \"#\": \"section\",\n        \"^\": \"inverted section\",\n        \"/\": \"end\",\n        \">\": \"partial\",\n        \"=\": \"set delimiter?\",\n        \"{\": \"no escape?\",\n        \"&\": \"no escape\",\n    }\n\n    # Get the tag\n    try:\n        tag, template = template.split(r_del, 1)\n    except ValueError as e:\n        msg = f\"unclosed tag at line {_CURRENT_LINE}\"\n        raise ChevronError(msg) from e\n\n    # Check for empty tags\n    if not tag.strip():\n        msg = f\"empty tag at line {_CURRENT_LINE}\"\n        raise ChevronError(msg)\n\n    # Find the type meaning of the first character\n    tag_type = tag_types.get(tag[0], \"variable\")\n\n    # If the type is not a variable\n    if tag_type != \"variable\":\n        # Then that first character is not needed\n        tag = tag[1:]\n\n    # If we might be a set delimiter tag\n    if tag_type == \"set delimiter?\":\n        # Double check to make sure we are\n        if tag.endswith(\"=\"):","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/langchain-ai/langchain/blob/e32fa9a52eab3b61ad7a45399bfde59b3e580fc4/libs/core/langchain_core/utils/mustache.py#L131-L167","documentation":"Raised by the vendored Mustache engine (`langchain_core.utils.mustache`, used by `MustachePlaceholderFormatter`) when a tag is opened with the left delimiter (`{{`) but the right delimiter (`}}`) is never found in the remainder of the template. The message reports the line where the unclosed tag starts. The template cannot be parsed at all, so no rendering happens.","triggerScenarios":"Rendering a prompt template through `MustachePlaceholderFormatter.format` (or `tokenize`) where the template contains an unmatched `{{`, e.g. `\"Summarize: {{text\"` or a literal `{{` intended as text (e.g. JSON examples embedded in a prompt) without escaping.","commonSituations":"Hand-written prompt templates with a typo (missing `}}`); embedding raw JSON or LaTeX (`{{ ... }}`) in a Mustache template without escaping; user-supplied templates passed to an agent loop that uses Mustache formatting; partial templates concatenated at runtime that cut a tag in half.","solutions":["Go to the reported line and close the tag or remove the stray `{{`.","If the double braces are literal content (JSON, LaTeX), change delimiters with a `{{=<% %>=}}` set-delimiter tag or escape/replace the braces before rendering.","Run `MustachePlaceholderFormatter` validation on templates at startup (compile/tokenize once) so the error surfaces before production traffic.","If templates come from users, lint them with the tokenizer before accepting."],"exampleFix":"# before\ntemplate = \"Q: {{question\\nA:\"  # missing closing braces\nMustachePlaceholderFormatter().format(template, question=\"hi\")  # ChevronError: unclosed tag\n\n# after\ntemplate = \"Q: {{question}}\\nA:\"\nMustachePlaceholderFormatter().format(template, question=\"hi\")","handlingStrategy":"validation","validationCode":"from langchain_core.utils.mustache import tokenize\nfrom langchain_core.utils.mustache import ChevronError\n\ndef validate_mustache(template: str) -> None:\n    try:\n        list(tokenize(template))\n    except ChevronError as e:\n        raise ValueError(f\"bad template: {e}\") from e","typeGuard":null,"tryCatchPattern":"try:\n    out = MustachePlaceholderFormatter().format(template, **vars)\nexcept ChevronError as e:\n    # fall back to str.format or raw template\n    out = template","preventionTips":["Tokenize templates once at startup/CI, not per request.","Escape literal double braces (JSON, LaTeX) or switch delimiters with a set-delimiter tag.","Keep templates in files under lint control rather than building them by string concatenation."],"tags":["mustache","prompt-template","parsing"],"backgroundTag":null,"analyzedSha":"e32fa9a52eab3b61ad7a45399bfde59b3e580fc4","analyzedAt":"2026-08-14T18:42:09.092Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}