langchain-ai/langchain · error · ValueError
Unexpected arguments for placeholder message type. Expected
Error message
Unexpected arguments for placeholder message type. Expected either a single string variable name or a list of [variable_name: str, is_optional: bool]. Got: {template} What it means
Raised in _create_template_from_message_type when a "placeholder" message's template value is neither a string nor a 2-element sequence [variable_name, is_optional]. The code tries to unpack the value into (var_name_wrapped, is_optional) and a ValueError from unpacking means the shape is wrong — e.g. a 3-element list or an empty one.
Source
Thrown at libs/core/langchain_core/prompts/chat.py:1391
if template[0] != "{" or template[-1] != "}":
msg = (
f"Invalid placeholder template: {template}."
" Expected a variable name surrounded by curly braces."
)
raise ValueError(msg)
var_name = template[1:-1]
message = MessagesPlaceholder(variable_name=var_name, optional=True)
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:View on GitHub (pinned to e32fa9a52e)
Solutions
- Use exactly two elements: ("placeholder", ["{variable_name}", is_optional_bool]).
- For a required placeholder, use the string form ("placeholder", "{variable_name}") which defaults optional=True only via structured form — note the string form creates optional=True; use the list form with False for required.
- Remove any extra list elements beyond [name, bool].
Example fix
# before
ChatPromptTemplate.from_messages([("placeholder", ["{history}", True, 0])])
# after
ChatPromptTemplate.from_messages([("placeholder", ["{history}", True])]) Defensive patterns
Strategy: validation
Validate before calling
def valid_placeholder_spec(t):
if isinstance(t, str):
return True
return isinstance(t, (list, tuple)) and len(t) == 2 Type guard
def is_placeholder_spec(t) -> bool:
return isinstance(t, str) or (isinstance(t, (list, tuple)) and len(t) == 2) Prevention
- Keep placeholder specs to exactly ["{name}", bool].
- Validate externally sourced message specs before from_messages.
When it happens
Trigger: `ChatPromptTemplate.from_messages([("placeholder", ["{history}", True, "extra"])])` (3 items), or ("placeholder", ["{history}"]) (1 item), or ("placeholder", 123) (non-iterable).
Common situations: Attempting to pass extra options to the placeholder (like optional plus a default), or passing the variable name wrapped in a list of wrong length when migrating from older tuple APIs.
Related errors
- Invalid placeholder template: {template}. Expected a variabl
- Invalid placeholder template: {var_name_wrapped}. Expected a
- Expected is_optional to be a boolean. Got: {is_optional}
- Expected variable name to be a string. Got: {var_name_wrappe
- Unexpected message type: {message_type}. Use one of 'human',
AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14).
Data as JSON: /api/errors/58dd9031d8663970.
Report an issue: GitHub.