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

  1. Annotate the handler with every concrete message type it accepts (union annotation), since matching is exact type() not isinstance
  2. Ensure the sender serializes/deserializes to the exact same class the handler annotates (same model definition on both sides)
  3. 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

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


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