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

  1. Inspect the dict passed to create() and add the correct 'type' key matching a registered message class name (e.g. data['type'] = 'TextMessage').
  2. If serializing messages yourself, use message.dump() instead of manually building the dict — dump() always emits 'type'.
  3. If a custom message class is involved, verify its dump() override includes 'type': type(self).__name__ or equivalent.
  4. 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

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


AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15). Data as JSON: /api/errors/48c50240ece6a340. Report an issue: GitHub.