{"record":{"id":"b05ed659eb8fef5d","repo":"langchain-ai/langchain","slug":"variable-self-variable-name-should-be-a-list-of","errorCode":null,"errorMessage":"variable {self.variable_name} should be a list of base messages, got {value} of type {type(value)}","messagePattern":"variable (.+?) should be a list of base messages, got (.+?) of type (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/core/langchain_core/prompts/chat.py","lineNumber":186,"sourceCode":"            **kwargs: Keyword arguments to use for formatting.\n\n        Returns:\n            List of `BaseMessage` objects.\n\n        Raises:\n            ValueError: If variable is not a list of messages.\n        \"\"\"\n        value = (\n            kwargs.get(self.variable_name, [])\n            if self.optional\n            else kwargs[self.variable_name]\n        )\n        if not isinstance(value, list):\n            msg = (\n                f\"variable {self.variable_name} should be a list of base messages, \"\n                f\"got {value} of type {type(value)}\"\n            )\n            raise ValueError(msg)  # noqa: TRY004\n        value = convert_to_messages(value)\n        if self.n_messages:\n            value = value[-self.n_messages :]\n        return value\n\n    @property\n    def input_variables(self) -> list[str]:\n        \"\"\"Input variables for this prompt template.\n\n        Returns:\n            List of input variable names.\n        \"\"\"\n        return [self.variable_name] if not self.optional else []\n\n    @override\n    def pretty_repr(self, html: bool = False) -> str:\n        \"\"\"Human-readable representation.\n","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/langchain-ai/langchain/blob/e32fa9a52eab3b61ad7a45399bfde59b3e580fc4/libs/core/langchain_core/prompts/chat.py#L168-L204","documentation":"MessagesPlaceholder._format_messages requires the value bound to its variable to be a Python list (it may be empty, and may be omitted entirely when optional=True). Any other type — a single BaseMessage, a tuple, a generator, None for a non-optional placeholder — raises ValueError telling you it wants 'a list of base messages'.","triggerScenarios":"Invoking a ChatPromptTemplate containing MessagesPlaceholder('history') with history=SystemMessage(...), history=(msg1, msg2), or history=msg_generator; passing None when the placeholder is not marked optional=True.","commonSituations":"Conversation-history wiring: retrieving a single last message instead of a list; passing a tuple from a DB row; forgetting to set optional_messages=True for branches where history may be absent.","solutions":["Always pass a list: {'history': [m1, m2]} or list(history_tuple)","If the value can be absent, declare MessagesPlaceholder('history', optional=True) so kwargs default to []","Convert a single message by wrapping it: {'history': [single_msg]}"],"exampleFix":"# before\nprompt = ChatPromptTemplate.from_messages([\n    MessagesPlaceholder(\"history\"), \"human: {q}\",\n])\nprompt.invoke({\"history\": SystemMessage(\"be terse\"), \"q\": \"hi\"})  # ValueError\n\n# after\nprompt.invoke({\"history\": [SystemMessage(\"be terse\")], \"q\": \"hi\"})","handlingStrategy":"type-guard","validationCode":"from langchain_core.messages import BaseMessage\n\ndef coerce_history(value):\n    if isinstance(value, BaseMessage):\n        return [value]\n    if not isinstance(value, list):\n        msg = f\"history must be a list of messages, got {type(value)}\"\n        raise ValueError(msg)\n    return list(value)","typeGuard":"def is_message_list(value) -> bool:\n    return isinstance(value, list) and all(isinstance(m, BaseMessage) for m in value)","tryCatchPattern":null,"preventionTips":["Declare MessagesPlaceholder('history', optional=True) whenever history may be absent","Always wrap single messages in a list at the call site"],"tags":["prompts","chat","messages","validation","core"],"backgroundTag":null,"analyzedSha":"e32fa9a52eab3b61ad7a45399bfde59b3e580fc4","analyzedAt":"2026-08-14T18:42:09.092Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}