langchain-ai/langchain · error · ValueError

Expected variable name to be a string. Got: {var_name_wrappe

Error message

Expected variable name to be a string. Got: {var_name_wrapped}

What it means

Raised in _create_template_from_message_type when the structured placeholder spec's first element (the variable name) is not a str, e.g. ("placeholder", [123, True]). The name must be a string like "{history}" so braces can be stripped.

Source

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

        else:
            try:
                var_name_wrapped, is_optional = template
            except ValueError as e:
                msg = (
                    "Unexpected arguments for placeholder message type."
                    " 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

View on GitHub (pinned to e32fa9a52e)

Solutions

  1. Convert the first element to a string wrapped in braces: f"{{{var_name}}}".
  2. Validate spec shape before calling from_messages when specs come from user/config input.

Example fix

# before
var_id = 7
ChatPromptTemplate.from_messages([("placeholder", [var_id, True])])

# after
var_id = 7
ChatPromptTemplate.from_messages([("placeholder", [f"{{{var_id}}}", True])])
Defensive patterns

Strategy: validation

Validate before calling

def valid_placeholder_name(spec):
    return isinstance(spec[0], str)

Type guard

def is_str_var_name(spec) -> bool:
    return len(spec) == 2 and isinstance(spec[0], str)

Prevention

When it happens

Trigger: `("placeholder", [42, True])`, or a config pipeline that yields the variable name as a Symbol/enum object instead of a string.

Common situations: Programmatically generated message specs where identifiers come from an enum, int ID, or object attribute that wasn't converted to str.

Related errors


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