microsoft/autogen · error · ValueError
Field 'type' is required in the message data to recover the
Error message
Field 'type' is required in the message data to recover the message type.
What it means
Thrown by MessageFactory.create() when deserializing a message from a dict that has no 'type' key. Every message in AutoGen AgentChat round-trips through a discriminated-union scheme where the 'type' string (e.g. 'TextMessage', 'ToolCallSummaryMessage') selects the registered class to reconstruct. Without it the factory cannot know which class's load() to call.
Source
Thrown at python/packages/autogen-agentchat/src/autogen_agentchat/messages.py:633
def register(self, message_type: type[BaseAgentEvent | BaseChatMessage]) -> None:
"""Register a new message type with the factory."""
if self.is_registered(message_type):
raise ValueError(f"Message type {message_type} is already registered.")
if not issubclass(message_type, BaseChatMessage) and not issubclass(message_type, BaseAgentEvent):
raise ValueError(f"Message type {message_type} must be a subclass of BaseChatMessage or BaseAgentEvent.")
# Get the class name of the
class_name = message_type.__name__
# Check if the class name is already registered.
# Register the message type.
self._message_types[class_name] = message_type
def create(self, data: Mapping[str, Any]) -> BaseAgentEvent | BaseChatMessage:
"""Create a message from a dictionary of JSON-serializable data."""
# Get the type of the message from the dictionary.
message_type = data.get("type")
if message_type is None:
raise ValueError("Field 'type' is required in the message data to recover the message type.")
if message_type not in self._message_types:
raise ValueError(f"Unknown message type: {message_type}")
if not isinstance(message_type, str):
raise ValueError(f"Message type must be a string, got {type(message_type)}")
# Get the class for the message type.
message_class = self._message_types[message_type]
# Create an instance of the message class.
assert issubclass(message_class, BaseChatMessage) or issubclass(message_class, BaseAgentEvent)
return message_class.load(data)
ChatMessage = Annotated[
TextMessage | MultiModalMessage | StopMessage | ToolCallSummaryMessage | HandoffMessage,
Field(discriminator="type"),
]
"""The union type of all built-in concrete subclasses of :class:`BaseChatMessage`.View on GitHub (pinned to 027ecf0a37)
Solutions
- Inspect the dict passed to create() and add the correct 'type' key matching a registered message class name (e.g. data['type'] = 'TextMessage').
- If serializing messages yourself, use message.dump() instead of manually building the dict — dump() always emits 'type'.
- If a custom message class is involved, verify its dump() override includes 'type': type(self).__name__ or equivalent.
- If loading old saved state, re-save it with the current version or migrate the state file to include 'type' fields.
Example fix
// before
msg = factory.create({"content": "hi", "source": "user"}) # ValueError
// after
msg = factory.create({"type": "TextMessage", "content": "hi", "source": "user"}) Defensive patterns
Strategy: validation
Validate before calling
def has_valid_type_field(data: Mapping[str, Any]) -> bool:
t = data.get("type")
return isinstance(t, str) and len(t) > 0 Type guard
from typing import Any, Mapping
def is_serialized_message(data: Any) -> bool:
return isinstance(data, Mapping) and isinstance(data.get("type"), str) Try / catch
try:
msg = factory.create(data)
except ValueError as e:
if "'type' is required" in str(e):
raise ValueError(f"payload missing 'type': {data!r}") from e
raise Prevention
- Always produce serialized messages with message.dump() rather than hand-built dicts.
- When persisting messages, store the full dump() output including 'type'.
- Add a schema check on loaded checkpoints before passing them to create().
When it happens
Trigger: Calling MessageFactory.create(data) (directly or via team state loading / serialized checkpoint restore) with a dict missing the 'type' key, e.g. {'content': 'hi', 'source': 'user'}. Also occurs when a custom serialization path drops or renames the 'type' field before calling create().
Common situations: Restoring a team checkpoint saved with an older serialization format, hand-building message dicts for replay/testing, or a custom message class whose dump()/load() implementation forgets to include 'type'.
Related errors
- Unknown message type: {message_type}
- Message type must be a string, got {type(message_type)}
- Message type {msg.__class__} is not registered with the mess
- Unsupported payload serialization format: {payload_serializa
- Unsupported message content type: {message_content_type}
AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15).
Data as JSON: /api/errors/48c50240ece6a340.
Report an issue: GitHub.