microsoft/autogen · error · AssertionError

Message type not found

Error message

Message type not found

What it means

The same introspection helper requires the closure's second parameter (the message) to carry a resolvable type annotation that get_types() can extract. If the message parameter is unannotated, annotated Any, or its annotation cannot be resolved to concrete types, AssertionError('Message type not found') fires.

Source

Thrown at python/packages/autogen-core/src/autogen_core/_closure_agent.py:43

def get_handled_types_from_closure(
    closure: Callable[[ClosureAgent, T, MessageContext], Awaitable[Any]],
) -> Sequence[type]:
    args = inspect.getfullargspec(closure)[0]
    if len(args) != 3:
        raise AssertionError("Closure must have 4 arguments")

    message_arg_name = args[1]

    type_hints = get_type_hints(closure)

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

    # Get the type of the message parameter
    target_types = get_types(type_hints[message_arg_name])
    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")

    return target_types


class ClosureContext(Protocol):
    @property
    def id(self) -> AgentId: ...

    async def send_message(
        self,
        message: Any,
        recipient: AgentId,

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. Annotate the message parameter with the concrete message type: async def handler(agent, message: MyMessage, ctx) -> None.
  2. Ensure the annotation type is imported where the closure is defined so get_type_hints can evaluate it.
  3. Avoid Any or bare object annotations; register a separate closure per message type if you handle several.

Example fix

# before
async def handler(agent, message, ctx) -> None:  # message unannotated
    ...

# after
async def handler(agent: ClosureContext, message: TextMessage, ctx: MessageContext) -> None:
    ...
Defensive patterns

Strategy: validation

Validate before calling

from typing import get_type_hints

hints = get_type_hints(my_closure)
msg_type = hints.get("message")  # or the actual parameter name
assert msg_type is not None and msg_type is not object, "annotate the message parameter with a concrete type"

Prevention

When it happens

Trigger: async def handler(agent, message, ctx) -> None with no annotation on message; annotating message as Any; forward-reference annotations that get_type_hints cannot resolve; Union/None annotations for which get_types returns None.

Common situations: Generic handlers meant to accept 'anything' (use explicit routing or multiple registrations instead); missing imports for annotation types; annotation stripping by decorators or exec-based code.

Related errors


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