Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ChatPromptTemplate with template_format='mustache' threat placeholder still a f-string #30131

Open
5 tasks done
skabbit opened this issue Mar 6, 2025 · 1 comment
Open
5 tasks done
Labels
🤖:bug Related to a bug, vulnerability, unexpected error with an existing feature Ɑ: core Related to langchain-core

Comments

@skabbit
Copy link

skabbit commented Mar 6, 2025

Checked other resources

  • I added a very descriptive title to this issue.
  • I searched the LangChain documentation with the integrated search.
  • 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).

Example Code

from langchain_core.prompts import ChatPromptTemplate
from langchain_core.messages import AIMessage, HumanMessage


def test_prompt_template_bug():
    template = ChatPromptTemplate([
            ('system', ''),
            ('placeholder', '{{messages}}'),
            ('user', '{{user_input}}'),
        ], template_format='mustache')

    prompt_value = template.invoke({
        "user_input": "User input!",
        "messages": [HumanMessage(content="messages")]
    })
    assert len(prompt_value.messages) == 3

Error Message and Stack Trace (if applicable)

No response

Description

Hi Langchain,

I found strange inconsistency with ChatPromptTemplate with template_format='mustache', see attached code. I expected that placeholder formatting will use similar template format engine, but it remains f-string.

Test code assertion would fail, and only replacing {{messages}} with {messages} would fix it.

If this is intentionally, then probably it should be reflected in documentation, which is not currently.

Thank you.

System Info

System Information

OS: Linux
OS Version: #1 SMP Thu Feb 27 20:22:48 UTC 2020
Python Version: 3.9.6 (default, Feb 28 2022, 11:53:11)
[GCC 7.3.1 20180712 (Red Hat 7.3.1-9)]

Package Information

langchain_core: 0.3.41
langchain: 0.3.7
langchain_community: 0.3.5
langsmith: 0.1.147
langchain_openai: 0.2.0
langchain_postgres: 0.0.12
langchain_text_splitters: 0.3.0
langgraph_sdk: 0.1.42

Optional packages not installed

langserve

Other Dependencies

aiohttp: 3.11.9
async-timeout: 4.0.3
dataclasses-json: 0.6.7
httpx: 0.28.0
httpx-sse: 0.4.0
jsonpatch<2.0,>=1.33: Installed. No version info available.
langsmith-pyo3: Installed. No version info available.
langsmith<0.4,>=0.1.125: Installed. No version info available.
numpy: 1.26.4
openai: 1.56.2
orjson: 3.10.12
packaging<25,>=23.2: Installed. No version info available.
pgvector: 0.2.5
psycopg: 3.2.3
psycopg-pool: 3.2.4
pydantic: 2.10.3
pydantic-settings: 2.4.0
pydantic<3.0.0,>=2.5.2;: Installed. No version info available.
pydantic<3.0.0,>=2.7.4;: Installed. No version info available.
PyYAML: 6.0.2
PyYAML>=5.3: Installed. No version info available.
requests: 2.32.3
requests-toolbelt: 1.0.0
sqlalchemy: 2.0.29
SQLAlchemy: 2.0.29
tenacity: 9.0.0
tenacity!=8.4.0,<10.0.0,>=8.1.0: Installed. No version info available.
tiktoken: 0.7.0
typing-extensions>=4.7: Installed. No version info available.

@dosubot dosubot bot added Ɑ: core Related to langchain-core 🤖:bug Related to a bug, vulnerability, unexpected error with an existing feature labels Mar 6, 2025
@YassinNouh21
Copy link

@skabbit

The Issue

When using template_format='mustache', you would expect all variable placeholders to follow mustache syntax ({{variable}}), but the MessagesPlaceholder still expects the f-string format ({variable}).

Let's look at how to fix this:

Solution

You need to use {messages} for the placeholder variable name, even when the template format is set to mustache:

from langchain_core.prompts import ChatPromptTemplate
from langchain_core.messages import AIMessage, HumanMessage

def test_prompt_template_bug():
    template = ChatPromptTemplate([
            ('system', ''),
            ('placeholder', '{messages}'),  # Use f-string format here
            ('user', '{{user_input}}'),     # Use mustache format here
        ], template_format='mustache')

    prompt_value = template.invoke({
        "user_input": "User input!",
        "messages": [HumanMessage(content="messages")]
    })
    assert len(prompt_value.messages) == 3

Why This Happens

Looking at the codebase, the MessagesPlaceholder class in doesn't respect the template format setting of the parent ChatPromptTemplate. It always uses the variable name directly without any template formatting.

From the code snippet at line 274-275:

var = "{" + self.variable_name + "}"
if html:
    title = get_msg_title_repr("Messages Placeholder", bold=True)
    var = get_colored_text(var, "yellow")

This is why you need to use {messages} instead of {{messages}} for the placeholder variable name.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🤖:bug Related to a bug, vulnerability, unexpected error with an existing feature Ɑ: core Related to langchain-core
Projects
None yet
Development

No branches or pull requests

2 participants