{"record":{"id":"d1ddb9552ad9f526","repo":"langchain-ai/langchain","slug":"got-unexpected-message-type-type","errorCode":null,"errorMessage":"Got unexpected message type: {type_}","messagePattern":"Got unexpected message type: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/core/langchain_core/messages/utils.py","lineNumber":544,"sourceCode":"        return FunctionMessage(**message[\"data\"])\n    if type_ == \"tool\":\n        return ToolMessage(**message[\"data\"])\n    if type_ == \"remove\":\n        return RemoveMessage(**message[\"data\"])\n    if type_ == \"AIMessageChunk\":\n        return AIMessageChunk(**message[\"data\"])\n    if type_ == \"HumanMessageChunk\":\n        return HumanMessageChunk(**message[\"data\"])\n    if type_ == \"FunctionMessageChunk\":\n        return FunctionMessageChunk(**message[\"data\"])\n    if type_ == \"ToolMessageChunk\":\n        return ToolMessageChunk(**message[\"data\"])\n    if type_ == \"SystemMessageChunk\":\n        return SystemMessageChunk(**message[\"data\"])\n    if type_ == \"ChatMessageChunk\":\n        return ChatMessageChunk(**message[\"data\"])\n    msg = f\"Got unexpected message type: {type_}\"\n    raise ValueError(msg)\n\n\ndef messages_from_dict(messages: Sequence[dict[str, Any]]) -> list[BaseMessage]:\n    \"\"\"Convert a sequence of messages from dicts to `Message` objects.\n\n    Args:\n        messages: Sequence of messages (as dicts) to convert.\n\n    Returns:\n        list of messages (BaseMessages).\n\n    \"\"\"\n    return [_message_from_dict(m) for m in messages]\n\n\ndef message_chunk_to_message(chunk: BaseMessage) -> BaseMessage:\n    \"\"\"Convert a message chunk to a `Message`.\n","sourceCodeStart":526,"sourceCodeEnd":562,"githubUrl":"https://github.com/langchain-ai/langchain/blob/e32fa9a52eab3b61ad7a45399bfde59b3e580fc4/libs/core/langchain_core/messages/utils.py#L526-L562","documentation":"Raised by the internal message-deserialization dispatch (used by `messages_from_dict`) when the 'type' string of a serialized message does not match any known class name ('HumanMessage', 'AIMessageChunk', 'ToolMessageChunk', etc.). The deserializer only instantiates from a fixed allowlist of type strings.","triggerScenarios":"Calling `messages_from_dict` on dicts whose 'type' field is a misspelled or unknown class name, e.g. `{'type': 'humanmessage', 'data': {...}}` or a type from a newer/older langchain version.","commonSituations":"Loading chat histories persisted by a different langchain-core version that serialized a class name this version dropped or renamed; hand-edited JSON logs; cross-system message exchange where one side uses non-standard type strings.","solutions":["Check the exact 'type' spelling against the supported list (HumanMessage, AIMessage, SystemMessage, FunctionMessage, ToolMessage, ChatMessage and their Chunk variants)","If data comes from another version, map/normalize type strings before deserializing","Re-serialize messages with the current langchain-core version so type names match"],"exampleFix":"# before\nmessages_from_dict([{'type': 'human_message', 'data': {'content': 'hi'}}])\n\n# after\nmessages_from_dict([{'type': 'HumanMessage', 'data': {'content': 'hi', 'type': 'human'}}])","handlingStrategy":"validation","validationCode":"KNOWN_TYPES = {'HumanMessage', 'AIMessage', 'SystemMessage', 'FunctionMessage',\n               'ToolMessage', 'ChatMessage', 'AIMessageChunk', 'HumanMessageChunk',\n               'FunctionMessageChunk', 'ToolMessageChunk', 'SystemMessageChunk', 'ChatMessageChunk'}\n\ndef deserializable(d: dict) -> bool:\n    return d.get('type') in KNOWN_TYPES","typeGuard":"def is_known_serialized_type(d: dict) -> bool:\n    return isinstance(d, dict) and d.get('type') in KNOWN_TYPES","tryCatchPattern":"try:\n    msgs = messages_from_dict(data)\nexcept ValueError as e:\n    if 'unexpected message type' in str(e):\n        data = normalize_type_strings(data)  # map old/misspelled names\n        msgs = messages_from_dict(data)\n    else:\n        raise","preventionTips":["Persist messages with the same langchain-core version that will read them","Normalize type strings after cross-version data migration","Round-trip test serialization/deserialization for custom persisted formats"],"tags":["serialization","deserialization","persistence"],"backgroundTag":null,"analyzedSha":"e32fa9a52eab3b61ad7a45399bfde59b3e580fc4","analyzedAt":"2026-08-14T18:42:09.092Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}