{"record":{"id":"81fdeb403cf89b13","repo":"microsoft/semantic-kernel","slug":"return-type-not-found-please-use-none-as-the-ty","errorCode":null,"errorMessage":"Return type not found. Please use `None` as the type hint of the return type.","messagePattern":"Return type not found\\. Please use `None` as the type hint of the return type\\.","errorType":"exception","errorClass":"AssertionError","httpStatus":null,"severity":"error","filePath":"python/semantic_kernel/agents/runtime/core/routed_agent.py","lineNumber":276,"sourceCode":"    def decorator(\n        func: Callable[[AgentT, ReceivesT, MessageContext], Coroutine[Any, Any, None]],\n    ) -> MessageHandler[AgentT, ReceivesT, None]:\n        type_hints = get_type_hints(func)\n        if \"message\" not in type_hints:\n            raise AssertionError(\"message parameter not found in function signature\")\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\"])\n        if target_types is None:\n            raise AssertionError(\"Message type not found. Please provide a type hint for the message parameter.\")\n\n        return_types = get_types(type_hints[\"return\"])\n\n        if return_types is None:\n            raise AssertionError(\"Return type not found. Please use `None` as the type hint of the return type.\")\n\n        # Convert target_types to list and stash\n\n        @wraps(func)\n        async def wrapper(self: AgentT, message: ReceivesT, ctx: MessageContext) -> None:\n            if type(message) not in target_types:\n                if strict:\n                    raise CantHandleException(f\"Message type {type(message)} not in target types {target_types}\")\n                logger.warning(f\"Message type {type(message)} not in target types {target_types}\")\n\n            return_value = await func(self, message, ctx)  # type: ignore\n\n            if return_value is not None:\n                if strict:\n                    raise ValueError(f\"Return type {type(return_value)} is not None.\")\n                logger.warning(f\"Return type {type(return_value)} is not None. It will be ignored.\")\n\n            return","sourceCodeStart":258,"sourceCodeEnd":294,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/python/semantic_kernel/agents/runtime/core/routed_agent.py#L258-L294","documentation":"Raised at decoration time by the @event decorator. After confirming a 'return' annotation exists, it calls get_types() to extract concrete types. If the annotation is not interpretable as a class/Union/Optional/Any/NoneType (for example a typing special form like NoReturn/Never, a TypeVar, a parametrized generic alias such as list[int], or a Literal), get_types returns None and the decorator raises this AssertionError. Event handlers must return None, so the return annotation must be -> None.","triggerScenarios":"Decorating a method with @event whose return annotation is present but not a resolvable concrete type, e.g. -> NoReturn, -> T (a TypeVar), -> list[int], -> Literal['x'], or -> NewType. Annotating with -> None (resolved to NoneType) does NOT trigger this.","commonSituations":"Copying a handler from an RPC sample and leaving an exotic return hint; using a TypeVar/NewType as the return annotation; refactoring without fixing the return hint.","solutions":["Annotate the handler return as -> None.","If the handler must return a value, use the @rpc decorator instead of @event.","Avoid TypeVar, Literal, parametrized generic aliases, and NoReturn/Never as return annotations on event handlers."],"exampleFix":"// before\n@event\nasync def on_event(self, msg: MyEvent, ctx: MessageContext) -> NoReturn:\n    ...\n\n// after\n@event\nasync def on_event(self, msg: MyEvent, ctx: MessageContext) -> None:\n    ...","handlingStrategy":"validation","validationCode":"from typing import get_type_hints\nfrom semantic_kernel.agents.runtime.core.type_helpers import get_types\n\ndef event_return_ok(fn) -> bool:\n    hints = get_type_hints(fn)\n    if 'return' not in hints:\n        return False\n    return get_types(hints['return']) is not None","typeGuard":"from types import NoneType\n\ndef returns_none(fn) -> bool:\n    from typing import get_type_hints\n    hints = get_type_hints(fn)\n    return hints.get('return') in (NoneType, type(None))","tryCatchPattern":null,"preventionTips":["Always annotate @event handlers with -> None.","Assert get_type_hints(handler)['return'] resolves in unit tests for every handler.","Run mypy/pyright with disallow_untyped_defs to force complete annotations."],"tags":["event-handler","type-hints","decorator","assertion","startup"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}