microsoft/autogen · error · AssertionError

Message type not found

Error message

Message type not found

What it means

The @message_handler (and equivalently @rpc) decorator inspects the decorated coroutine's type hints and requires the 'message' parameter's annotation to resolve to at least one concrete type. get_types() returned None, meaning the annotation is missing, None, or an unsupported construct (e.g. a bare TypeVar, unparameterized generic, or unresolvable forward reference). The library throws at decoration/import time so handlers always carry routable target types.

Source

Thrown at python/packages/autogen-core/src/autogen_core/_routed_agent.py:131

        func: The function to be decorated.
        strict: If `True`, the handler will raise an exception if the message type or return type is not in the target types. If `False`, it will log a warning instead.
        match: A function that takes the message and the context as arguments and returns a boolean. This is used for secondary routing after the message type. For handlers addressing the same message type, the match function is applied in alphabetical order of the handlers and the first matching handler will be called while the rest are skipped. If `None`, the first handler in alphabetical order matching the same message type will be called.
    """

    def decorator(
        func: Callable[[AgentT, ReceivesT, MessageContext], Coroutine[Any, Any, ProducesT]],
    ) -> MessageHandler[AgentT, ReceivesT, ProducesT]:
        type_hints = get_type_hints(func)
        if "message" not in type_hints:
            raise AssertionError("message parameter not found in function signature")

        if "return" not in type_hints:
            raise AssertionError("return parameter not found in function signature")

        # 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)

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. Annotate the message parameter with a concrete message class: async def handle(self, message: MyMessageType, ctx: MessageContext) -> MyResponse
  2. If using a string annotation, import the type at runtime (not only under TYPE_CHECKING) so get_type_hints can resolve it
  3. For unions of message types, annotate with each concrete class (e.g. message: MessageTypeA | MessageTypeB) rather than a TypeVar or base 'object'

Example fix

# before
@message_handler
async def handle(self, message, ctx: MessageContext) -> None: ...

# after
@message_handler
async def handle(self, message: MyMessageType, ctx: MessageContext) -> None: ...
Defensive patterns

Strategy: validation

Validate before calling

from typing import get_type_hints

def handler_hints_ok(func) -> bool:
    hints = get_type_hints(func)
    return "message" in hints and hints["message"] is not None and hints["message"] is not type(None)

Type guard

def has_valid_message_hint(func) -> bool:
    hints = get_type_hints(func)
    m = hints.get("message")
    return m is not None and m not in (type(None), object) and not str(m).startswith("typing.TypeVar")

Prevention

When it happens

Trigger: Decorating a handler whose signature is async def handle(self, message) (no annotation), async def handle(self, message: None), or async def handle(self, message: SomeUnresolvableType) where the forward-ref string cannot be resolved by get_type_hints in the module namespace.

Common situations: Copying a plain method into a RoutedAgent without adding annotations; using string/forward annotations for types imported under TYPE_CHECKING; annotating with an unparameterized generic like Sequence or a protocol/typevar instead of a concrete message class.

Related errors


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