langchain-ai/langchain · error · ValueError
Unexpected input: {message_template}
Error message
Unexpected input: {message_template} What it means
ChatPromptTemplate.format_messages iterates self.messages and accepts BaseMessage instances, BaseMessagePromptTemplate, or BaseChatPromptTemplate; anything else is rejected with ValueError('Unexpected input: ...'). Type checkers mark the raise unreachable because the messages field is typed to those classes — hitting it at runtime means the field holds an untyped/foreign object, usually injected by direct construction or mutation bypassing validation.
Source
Thrown at libs/core/langchain_core/prompts/chat.py:1199
Raises:
ValueError: If messages are of unexpected types.
Returns:
List of formatted messages.
"""
kwargs = self._merge_partial_and_user_variables(**kwargs)
result = []
for message_template in self.messages:
if isinstance(message_template, BaseMessage):
result.extend([message_template])
elif isinstance(
message_template, (BaseMessagePromptTemplate, BaseChatPromptTemplate)
):
message = message_template.format_messages(**kwargs)
result.extend(message)
else:
msg = f"Unexpected input: {message_template}" # type: ignore[unreachable]
raise ValueError(msg) # noqa: TRY004
return result
async def aformat_messages(self, **kwargs: Any) -> list[BaseMessage]:
"""Async format the chat template into a list of finalized messages.
Args:
**kwargs: Keyword arguments to use for filling in template variables
in all the template messages in this chat template.
Returns:
List of formatted messages.
Raises:
ValueError: If unexpected input.
"""
kwargs = self._merge_partial_and_user_variables(**kwargs)
result = []
for message_template in self.messages:View on GitHub (pinned to e32fa9a52e)
Solutions
- Keep messages to BaseMessage / message-template objects; convert strings with HumanMessagePromptTemplate.from_template(s) before inserting
- Avoid mutating .messages after construction — build a new ChatPromptTemplate via from_messages
- If loading from external data, revalidate: reconstruct through from_messages rather than assigning raw lists
Example fix
# before
prompt.messages.append("Summarize the above") # later format_messages -> ValueError
# after
from langchain_core.prompts import HumanMessagePromptTemplate
prompt.messages.append(HumanMessagePromptTemplate.from_template("Summarize the above")) Defensive patterns
Strategy: validation
Validate before calling
from langchain_core.messages import BaseMessage
from langchain_core.prompts import BaseMessagePromptTemplate, BaseChatPromptTemplate
def valid_messages(msgs) -> bool:
return all(
isinstance(m, (BaseMessage, BaseMessagePromptTemplate, BaseChatPromptTemplate))
for m in msgs
) Type guard
def is_valid_chat_prompt_message(m) -> bool:
return isinstance(m, (BaseMessage, BaseMessagePromptTemplate, BaseChatPromptTemplate)) Prevention
- Never append raw strings/objects to prompt.messages; convert via HumanMessagePromptTemplate.from_template
- Rebuild prompts with from_messages instead of mutating .messages after construction
When it happens
Trigger: Building ChatPromptTemplate(messages=[42]) via model_construct or by mutating .messages after validation; inserting a plain string or custom object into the messages list of an existing template; deserializing a corrupted prompt representation.
Common situations: Dynamic prompt pipelines that append to prompt.messages at runtime; model_construct(...) fast paths that skip validators; interop code that loads prompt state from JSON without re-validation.
Related errors
- variable {self.variable_name} should be a list of base messa
- Invalid template: {tmpl}
- Invalid template: {template}
- Got mismatched input_variables. Expected: {input_vars}. Got:
- INVALID_PROMPT_INPUT
AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14).
Data as JSON: /api/errors/22076b5f278a0ca3.
Report an issue: GitHub.