{"record":{"id":"32f40d6b547ee089","repo":"microsoft/autogen","slug":"return-type-not-found","errorCode":null,"errorMessage":"Return type not found","messagePattern":"Return type not found","errorType":"exception","errorClass":"AssertionError","httpStatus":null,"severity":"error","filePath":"python/packages/autogen-core/src/autogen_core/_closure_agent.py","lineNumber":49,"sourceCode":"        raise AssertionError(\"Closure must have 4 arguments\")\n\n    message_arg_name = args[1]\n\n    type_hints = get_type_hints(closure)\n\n    if \"return\" not in type_hints:\n        raise AssertionError(\"return not found in function signature\")\n\n    # Get the type of the message parameter\n    target_types = get_types(type_hints[message_arg_name])\n    if target_types is None:\n        raise AssertionError(\"Message type not found\")\n\n    # print(type_hints)\n    return_types = get_types(type_hints[\"return\"])\n\n    if return_types is None:\n        raise AssertionError(\"Return type not found\")\n\n    return target_types\n\n\nclass ClosureContext(Protocol):\n    @property\n    def id(self) -> AgentId: ...\n\n    async def send_message(\n        self,\n        message: Any,\n        recipient: AgentId,\n        *,\n        cancellation_token: CancellationToken | None = None,\n        message_id: str | None = None,\n    ) -> Any: ...\n\n    async def publish_message(","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-core/src/autogen_core/_closure_agent.py#L31-L67","documentation":"Companion check to the previous two: the closure's return annotation must resolve via get_types() to concrete types. A declared-but-unresolvable return annotation (forward reference that fails, None-producing annotation shapes) triggers AssertionError('Return type not found') after the 'return' key existence check passed.","triggerScenarios":"async def handler(...) -> \"SomeUnimportedType\"; returning generics whose hints get_types cannot reduce; annotations referencing names deleted or shadowed at ClosureAgent construction time.","commonSituations":"Return types declared with quoted forward references to avoid circular imports; refactoring that renames the response type without updating the string annotation.","solutions":["Use a concrete, imported return type: -> None for fire-and-forget handlers, or -> MyResponse.","If avoiding circular imports, move shared message types into a separate module both sides import.","Verify get_type_hints(handler) resolves in a REPL before constructing the ClosureAgent."],"exampleFix":"# before\nasync def handler(agent, message: Msg, ctx) -> \"Resp\":  # Resp not resolvable\n    ...\n\n# after\nfrom myapp.types import Resp\nasync def handler(agent: ClosureContext, message: Msg, ctx: MessageContext) -> Resp:\n    ...","handlingStrategy":"validation","validationCode":"from typing import get_type_hints\n\nhints = get_type_hints(my_closure)\nassert hints.get(\"return\") is not None, \"return annotation must resolve to a concrete type\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Return concrete imported types from closures (None is fine for fire-and-forget).","Resolve circular imports by moving message/response types to a shared module.","Verify with typing.get_type_hints(closure) in a REPL before wiring into a runtime."],"tags":["autogen-core","closure-agent","type-hints","return-type"],"backgroundTag":null,"analyzedSha":"027ecf0a379bcc1d09956d46d12d44a3ad9cee14","analyzedAt":"2026-08-15T03:38:00.719Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}