{"record":{"id":"794552bdc41dd0b6","repo":"langchain-ai/langchain","slug":"empty-tag-at-line-current-line","errorCode":null,"errorMessage":"empty tag at line {_CURRENT_LINE}","messagePattern":"empty tag at line (.+?)","errorType":"exception","errorClass":"ChevronError","httpStatus":null,"severity":"error","filePath":"libs/core/langchain_core/utils/mustache.py","lineNumber":154,"sourceCode":"        \"^\": \"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(\"=\"):\n            tag_type = \"set delimiter\"\n            # Remove the equal sign\n            tag = tag[:-1]\n\n        # Otherwise we should complain","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/langchain-ai/langchain/blob/e32fa9a52eab3b61ad7a45399bfde59b3e580fc4/libs/core/langchain_core/utils/mustache.py#L136-L172","documentation":"Raised by the Mustache tokenizer in `langchain_core.utils.mustache` when a tag parses successfully (both delimiters found) but its body is empty or whitespace-only, e.g. `{{ }}` or `{{}}`. An empty tag has no variable name to look up, so it is rejected as malformed. The line number in the message is where the tag appears.","triggerScenarios":"Formatting a template with `MustachePlaceholderFormatter` that contains `{{}}`, `{{ }}`, or a tag whose name was removed by an editing mistake; frequently a leftover after deleting a variable name but leaving the braces.","commonSituations":"Editing prompt templates and deleting the variable name but not the braces; templating pipelines that substitute variable names with empty strings before rendering (`{{%s}} % var` with empty `var`); copy-pasted templates with placeholder braces meant to be filled in later.","solutions":["Find the empty tag on the reported line and either give it a name (`{{name}}`) or delete it.","If the tag was produced by string substitution, guard that the substituted name is non-empty before building the template.","Validate templates by tokenizing once at load time so malformed tags fail fast during development."],"exampleFix":"# before\ntemplate = \"Hello {{ }}!\"\nMustachePlaceholderFormatter().format(template)  # ChevronError: empty tag\n\n# after\ntemplate = \"Hello {{name}}!\"\nMustachePlaceholderFormatter().format(template, name=\"Ada\")","handlingStrategy":"validation","validationCode":"import re\n\ndef has_empty_tags(template: str) -> bool:\n    return bool(re.search(r\"\\{\\{\\s*\\}\\}\", template))\n\nif has_empty_tags(template):\n    raise ValueError(\"template contains an empty tag\")","typeGuard":null,"tryCatchPattern":"try:\n    list(tokenize(template))\nexcept ChevronError as e:\n    raise ValueError(f\"invalid template: {e}\") from e","preventionTips":["When generating tags by substitution, assert the name is non-empty before rendering.","Lint templates for {{}} / {{ }} patterns in CI.","Tokenize templates at load time."],"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"}