core: mustache inverted section `{{^key}}` nested inside a `{{#key}}` list section misrenders or raises `IndexError`
Submission checklist
- This is a bug, not a usage question.
- I added a clear and descriptive title that summarizes this issue.
- I used the GitHub search to find a similar question and didn't find it.
- I am sure that this is a bug in LangChain rather than my code.
- The bug is not resolved by updating to the latest stable version of LangChain (or the specific integration package).
- This is not related to the langchain-community package.
- I posted a self-contained, minimal, reproducible example. A maintainer can copy it and run it AS IS.
Package (Required)
- langchain
- langchain-openai
- langchain-anthropic
- langchain-classic
- langchain-core
- langchain-model-profiles
- langchain-tests
- langchain-text-splitters
- langchain-chroma
- langchain-deepseek
- langchain-exa
- langchain-fireworks
- langchain-groq
- langchain-huggingface
- langchain-mistralai
- langchain-nomic
- langchain-ollama
- langchain-openrouter
- langchain-perplexity
- langchain-qdrant
- langchain-xai
- Other / not sure / general
Related Issues / PRs
No response
Reproduction Steps / Example Code (Python)
from langchain_core.prompts import ChatPromptTemplate
# 1. Silently wrong output
prompt = ChatPromptTemplate.from_messages(
[("human", "{{#items}}[{{^items}}none{{/items}}{{name}}]{{/items}}")],
template_format="mustache",
)
print(repr(prompt.invoke({"items": [{"name": "a"}, {"name": "b"}]}).messages[0].content))
# Actual: '[[]'
# Expected: '[a][b]'
# 2. Crash
prompt = ChatPromptTemplate.from_messages(
[("human", "{{#items}}{{^items}}none{{/items}}{{/items}}Done")],
template_format="mustache",
)
prompt.invoke({"items": [{"name": "a"}, {"name": "b"}]})
# Actual: IndexError: list index out of range
# Expected: 'Done'
# The same happens when calling `langchain_core.utils.mustache.render` directly, e.g. `render("{{#items}}[{{^items}}none{{/items}}{{.}}]{{/items}}END", {"items": [1, 2]})` raises `IndexError` instead of returning `'[1][2]END'`.
Error Message and Stack Trace (if applicable)
Description
Error:
File ".../langchain_core/prompts/string.py", line 122, in mustache_formatter
return mustache.render(template, kwargs)
File ".../langchain_core/utils/mustache.py", line 525, in render
current_scope = scopes[0]
IndexError: list index out of range
When a section's value is a list, render() gathers the tokens up to the matching {{/key}} and tracks nesting with tags_with_same_key. The counter is incremented only for ("section", key) tokens, but decremented for every ("end", key) token. An inverted section with the same key ({{^items}}...{{/items}}) therefore never increments the counter, yet its closing tag decrements it, so the loop treats the inner {{/items}} as the end of the outer section.
The loop body is truncated, the remaining tokens render once outside the loop, and the extra end token pops a scope that was never pushed, which surfaces as IndexError or as silently wrong output depending on the template. Nesting an inverted section with the same key inside a section is valid mustache.
The depth counting was introduced for nested regular sections (#23747), but inverted sections were not covered, and the existing unit tests only exercise a top-level {{^key}}.
Proposed fix: count ("inverted section", key) as an opening tag alongside ("section", key) in that loop, and add regression tests for both render() and ChatPromptTemplate(template_format="mustache"). I'd be glad to open a PR with the fix and tests if a maintainer assigns this to me.
System Info
- langchain-core 1.6.3 (also current
master) - Python 3.10.16
- macOS 26.6 (arm64)
Social handles (optional)
No response
Source: langchain-ai/langchain