langchain-ai/langchain · error · ValueError

Invalid placeholder template: {var_name_wrapped}. Expected a

Error message

Invalid placeholder template: {var_name_wrapped}. Expected a variable name surrounded by curly braces.

What it means

Raised in _create_template_from_message_type when the structured placeholder spec's variable name is a string but does not start with '{' and end with '}'. The list form has the same brace requirement as the plain string form: ["{name}", optional].

Source

Thrown at libs/core/langchain_core/prompts/chat.py:1405

                    " Expected either a single string variable name"
                    " or a list of [variable_name: str, is_optional: bool]."
                    f" Got: {template}"
                )
                raise ValueError(msg) from e

            if not isinstance(is_optional, bool):
                msg = f"Expected is_optional to be a boolean. Got: {is_optional}"
                raise ValueError(msg)  # noqa: TRY004

            if not isinstance(var_name_wrapped, str):
                msg = f"Expected variable name to be a string. Got: {var_name_wrapped}"
                raise ValueError(msg)  # noqa: TRY004
            if var_name_wrapped[0] != "{" or var_name_wrapped[-1] != "}":
                msg = (
                    f"Invalid placeholder template: {var_name_wrapped}."
                    " Expected a variable name surrounded by curly braces."
                )
                raise ValueError(msg)
            var_name = var_name_wrapped[1:-1]

            message = MessagesPlaceholder(variable_name=var_name, optional=is_optional)
    else:
        msg = (
            f"Unexpected message type: {message_type}. Use one of 'human',"
            f" 'user', 'ai', 'assistant', or 'system'."
        )
        raise ValueError(msg)
    return message


def _convert_to_message_template(
    message: MessageLikeRepresentation,
    template_format: PromptTemplateFormat = "f-string",
) -> BaseMessage | BaseMessagePromptTemplate | BaseChatPromptTemplate:
    """Instantiate a message from a variety of message formats.

View on GitHub (pinned to e32fa9a52e)

Solutions

  1. Wrap the name in single braces: ["{history}", True].
  2. Remember in f-strings braces must be doubled or built as "{" + name + "}".
  3. Or use MessagesPlaceholder(variable_name="history", optional=True) directly, which takes the bare name.

Example fix

# before
ChatPromptTemplate.from_messages([("placeholder", ["history", True])])

# after
from langchain_core.prompts import MessagesPlaceholder
ChatPromptTemplate.from_messages([MessagesPlaceholder("history", optional=True)])
Defensive patterns

Strategy: validation

Validate before calling

def valid_braced_name(name):
    return isinstance(name, str) and len(name) >= 2 and name[0] == "{" and name[-1] == "}"

Prevention

When it happens

Trigger: `("placeholder", ["history", True])` — bare name without braces; or ["{history", True] with mismatched braces.

Common situations: Assuming the list form takes the bare variable name because MessagesPlaceholder(variable_name=...) does; template strings assembled by f-string that drop or double braces.

Related errors


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