microsoft/autogen · error · ValueError
Message type must be a string, got {type(message_type)}
Error message
Message type must be a string, got {type(message_type)} What it means
Intended to be raised when data['type'] is not a string (e.g. an int or bytes). Note the guard order in the source: the 'not in self._message_types' check runs first, so any non-string value that isn't a registered key already raises 'Unknown message type' before this branch. In practice this error is nearly unreachable; seeing it means a non-string type value collided with a registry lookup.
Source
Thrown at python/packages/autogen-agentchat/src/autogen_agentchat/messages.py:637
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`.
It does not include :class:`StructuredMessage` types."""
AgentEvent = Annotated[
ToolCallRequestEventView on GitHub (pinned to 027ecf0a37)
Solutions
- Coerce the field to a string before calling create(): data['type'] = str(data['type']).
- Fix the upstream producer so it always writes 'type' as a JSON string.
- If you hit this exact message (not 'Unknown message type'), audit any code that mutates the factory's _message_types registry with non-string keys.
Example fix
# before
factory.create({"type": 5, "content": "hi"})
# after
factory.create({"type": "TextMessage", "content": "hi"}) Defensive patterns
Strategy: validation
Validate before calling
if not isinstance(data.get("type"), str):
data = {**data, "type": str(data.get("type"))}
msg = factory.create(data) Type guard
def type_is_str(data: Mapping[str, Any]) -> bool:
return isinstance(data.get("type"), str) Prevention
- Ensure message payloads come from message.dump() or validated JSON schemas.
- Never mutate the factory registry with non-string keys.
- Validate external payloads against a pydantic model with type: str before create().
When it happens
Trigger: Calling MessageFactory.create() with data['type'] set to a non-string, non-None value (e.g. {'type': 5}) — though most such inputs actually fail earlier with 'Unknown message type' because registry keys are strings.
Common situations: Corrupted or externally produced message payloads where 'type' was encoded as a number or bytes; JSON-decoded data that went through a lossy transform.
Related errors
- Expected Memory, List[Memory], or None, got {type(memory)}
- Unsupported tool type: {type(tool)}
- Unsupported handoff type: {type(handoff)}
- Field 'type' is required in the message data to recover the
- Unknown message type: {message_type}
AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15).
Data as JSON: /api/errors/f75b8ad33a00d20b.
Report an issue: GitHub.