microsoft/autogen · error · CantHandleException
Message type {type(message)} not in target types {target_typ
Error message
Message type {type(message)} not in target types {target_types} What it means
At runtime the generated wrapper checks type(message) against the handler's target_types using exact type() membership. If the delivered message's concrete class is not in target_types and strict=True, CantHandleException is raised, which lets the RoutedAgent runtime try other handlers or respond with an Undeliverable error. With strict=False it only logs a warning and still calls the handler.
Source
Thrown at python/packages/autogen-core/src/autogen_core/_routed_agent.py:145
# Get the type of the message parameter
target_types = get_types(type_hints["message"])
if target_types is None:
raise AssertionError("Message type not found")
# print(type_hints)
return_types = get_types(type_hints["return"])
if return_types is None:
raise AssertionError("Return type not found")
# Convert target_types to list and stash
@wraps(func)
async def wrapper(self: AgentT, message: ReceivesT, ctx: MessageContext) -> ProducesT:
if type(message) not in target_types:
if strict:
raise CantHandleException(f"Message type {type(message)} not in target types {target_types}")
else:
logger.warning(f"Message type {type(message)} not in target types {target_types}")
return_value = await func(self, message, ctx)
if AnyType not in return_types and type(return_value) not in return_types:
if strict:
raise ValueError(f"Return type {type(return_value)} not in return types {return_types}")
else:
logger.warning(f"Return type {type(return_value)} not in return types {return_types}")
return return_value
wrapper_handler = cast(MessageHandler[AgentT, ReceivesT, ProducesT], wrapper)
wrapper_handler.target_types = list(target_types)
wrapper_handler.produces_types = list(return_types)
wrapper_handler.is_message_handler = True
wrapper_handler.router = match or (lambda _message, _ctx: True)View on GitHub (pinned to 027ecf0a37)
Solutions
- Annotate the handler with every concrete message type it accepts (union annotation), since matching is exact type() not isinstance
- Ensure the sender serializes/deserializes to the exact same class the handler annotates (same model definition on both sides)
- Set strict=False on the decorator to downgrade this to a warning if lenient routing is acceptable
Example fix
# before @message_handler async def handle(self, message: BaseMsg, ctx: MessageContext) -> None: ... # sender publishes SubMsg(BaseMsg) -> CantHandleException # after @message_handler async def handle(self, message: BaseMsg | SubMsg, ctx: MessageContext) -> None: ...
Defensive patterns
Strategy: try-catch
Validate before calling
from autogen_core import try_get_known_serializers_for_type
def can_handle(handler_wrapper, message) -> bool:
return type(message) in handler_wrapper.target_types Type guard
def message_in_target_types(handler, msg) -> bool:
return type(msg) in getattr(handler, "target_types", ()) Try / catch
from autogen_core import CantHandleException
try:
result = await agent.on_message(msg, ctx)
except CantHandleException:
# let the runtime pick another handler / report undeliverable
raise Prevention
- Share one message-models module between sender and receiver so concrete classes match exactly
- Remember routing is exact type() matching, not isinstance — annotate every concrete subclass you send
- Consider strict=False in prototypes to get warnings instead of exceptions while wiring routing
When it happens
Trigger: A sender publishes a different concrete message class than annotated (e.g. subclass instance of the annotated type, since type() matching is exact); multiple handlers exist and the message type was routed to a handler not declared for it; ctx.is_rpc semantics mismatch so a publish message reaches an rpc handler via @message_handler.
Common situations: Subclassing a message model and sending the subclass while the handler annotates the base class; version drift between sender and receiver message definitions; using @message_handler for both event and rpc traffic and receiving a type not in the annotation union.
Related errors
- Return type {type(return_value)} not in return types {return
- Return type {type(return_value)} is not None.
- Agent with name {id.type} is not of type {type.__name__}. It
- Message must have a receiver to be sent.
- str(message.error)
AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15).
Data as JSON: /api/errors/ecf8a55f23baaac8.
Report an issue: GitHub.