microsoft/autogen · error · AssertionError

Return type not found. Please use `None` as the type hint of

Error message

Return type not found. Please use `None` as the type hint of the return type.

What it means

The @event decorator requires the return annotation to resolve to a type, and for event handlers it must be None (events cannot produce responses). get_types() on the return hint returned None — either there is no return annotation at all, or it is an expression get_types cannot interpret (e.g. a TypeVar or unresolvable forward ref). The message tells you to use None as the return type hint.

Source

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

    def decorator(
        func: Callable[[AgentT, ReceivesT, MessageContext], Coroutine[Any, Any, None]],
    ) -> MessageHandler[AgentT, ReceivesT, None]:
        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. Please provide a type hint for the message parameter.")

        return_types = get_types(type_hints["return"])

        if return_types is None:
            raise AssertionError("Return type not found. Please use `None` as the type hint of the return type.")

        # Convert target_types to list and stash

        @wraps(func)
        async def wrapper(self: AgentT, message: ReceivesT, ctx: MessageContext) -> None:
            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)  # type: ignore

            if return_value is not None:
                if strict:
                    raise ValueError(f"Return type {type(return_value)} is not None.")
                else:
                    logger.warning(f"Return type {type(return_value)} is not None. It will be ignored.")

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. Change the return annotation to None: async def on_event(self, message: MyEvent, ctx: MessageContext) -> None
  2. If you actually need to return a response to the caller, use @rpc and annotate the response message type

Example fix

# before
@event
async def on_event(self, message: MyEvent, ctx: MessageContext) -> "T": ...

# after
@event
async def on_event(self, message: MyEvent, ctx: MessageContext) -> None: ...
Defensive patterns

Strategy: validation

Validate before calling

from typing import get_type_hints

def event_return_is_none(func) -> bool:
    hints = get_type_hints(func)
    return hints.get("return") is type(None) or hints.get("return") is None and False or hints.get("return") in (type(None),)

Type guard

def is_none_returning(func) -> bool:
    return get_type_hints(func).get("return") is type(None)

Prevention

When it happens

Trigger: Handler with no '-> ...' clause, or with '-> T' / '-> "SomeUnresolvedType"' instead of '-> None'.

Common situations: Copying an @rpc handler and switching the decorator to @event without changing the return annotation; omitting the return annotation entirely; generic handler mixins with TypeVar returns.

Related errors


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