microsoft/autogen · error · AssertionError
return not found in function signature
Error message
return not found in function signature
What it means
get_handled_types_from_closure() calls typing.get_type_hints(closure) and requires a 'return' entry to determine the closure's response type. A closure declared without a return annotation produces no 'return' key and AssertionError is raised. Note get_type_hints evaluates annotations, so string/forward-reference annotations that fail to resolve can also strip entries.
Source
Thrown at python/packages/autogen-core/src/autogen_core/_closure_agent.py:38
from .exceptions import CantHandleException
T = TypeVar("T")
ClosureAgentType = TypeVar("ClosureAgentType", bound="ClosureAgent")
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: ...View on GitHub (pinned to 027ecf0a37)
Solutions
- Annotate the return type explicitly: async def handler(agent, message, ctx) -> None (or the actual response type).
- Make sure any names used in annotations are importable in the closure's module scope (not under TYPE_CHECKING only).
- from __future__ import annotations is fine, but the referenced names must still resolve.
Example fix
# before
async def handler(agent, message, ctx): # no return annotation
agent.publish_message(...)
# after
async def handler(agent: ClosureContext, message: str, ctx: MessageContext) -> None:
await agent.publish_message(..., ctx=ctx) Defensive patterns
Strategy: validation
Validate before calling
from typing import get_type_hints hints = get_type_hints(my_closure) assert "return" in hints, "closure needs a return annotation (e.g. -> None)"
Prevention
- Fully annotate closures including the return type (-> None counts).
- Keep annotation-referenced types importable at runtime (not TYPE_CHECKING-only).
- Add a smoke test that constructs each ClosureAgent once to surface annotation errors early.
When it happens
Trigger: async def handler(agent, message, ctx): ... with no '-> SomeType' annotation; annotations given as unresolvable forward references (e.g. strings referencing names not imported at call time).
Common situations: Quick prototype closures written without annotations; using TYPE_CHECKING-only imports referenced in annotations; tools that strip annotations.
Related errors
- Message type not found
- Return type not found
- Closure must have 4 arguments
- ClosureAgent must be instantiated within the context of an A
- Message type {type(message)} not in target types {self._expe
AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15).
Data as JSON: /api/errors/6f6ed24014eabc89.
Report an issue: GitHub.