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

  1. Annotate the return type explicitly: async def handler(agent, message, ctx) -> None (or the actual response type).
  2. Make sure any names used in annotations are importable in the closure's module scope (not under TYPE_CHECKING only).
  3. 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

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


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