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
- Change the return annotation to None: async def on_event(self, message: MyEvent, ctx: MessageContext) -> None
- 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
- Standardize @event handlers as '-> None' in code review checklists
- Let the type checker verify handler signatures against the decorator's overloads
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
- Message type not found
- Return type not found
- Message type not found. Please provide a type hint for the m
- Invalid arguments
- No serializers found for type {type}. Please provide an expl
AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15).
Data as JSON: /api/errors/b903db00dcfe84dd.
Report an issue: GitHub.