{"record":{"id":"2d7e1dc69b0016cb","repo":"microsoft/semantic-kernel","slug":"return-type-type-return-value-not-in-return-typ","errorCode":null,"errorMessage":"Return type {type(return_value)} not in return types {return_types}","messagePattern":"Return type (.+?) not in return types (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/semantic_kernel/agents/runtime/core/routed_agent.py","lineNumber":160,"sourceCode":"        return_types = get_types(type_hints[\"return\"])\n\n        if return_types is None:\n            raise AssertionError(\"Return type not found\")\n\n        # Convert target_types to list and stash\n\n        @wraps(func)\n        async def wrapper(self: AgentT, message: ReceivesT, ctx: MessageContext) -> ProducesT:\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)\n\n            if AnyType not in return_types and type(return_value) not in return_types:\n                if strict:\n                    raise ValueError(f\"Return type {type(return_value)} not in return types {return_types}\")\n                logger.warning(f\"Return type {type(return_value)} not in return types {return_types}\")\n\n            return return_value\n\n        wrapper_handler = cast(MessageHandler[AgentT, ReceivesT, ProducesT], wrapper)\n        wrapper_handler.target_types = list(target_types)\n        wrapper_handler.produces_types = list(return_types)\n        wrapper_handler.is_message_handler = True\n        wrapper_handler.router = match or (lambda _message, _ctx: True)\n\n        return wrapper_handler\n\n    if func is None and not callable(func):\n        return decorator\n    if callable(func):\n        return decorator(func)\n    raise ValueError(\"Invalid arguments\")\n","sourceCodeStart":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/python/semantic_kernel/agents/runtime/core/routed_agent.py#L142-L178","documentation":"Raised at runtime by the @message_handler wrapper (strict mode) when the handler returns a value whose concrete type is not among its declared return types and the return is not typed Any. The runtime uses return-type metadata to route replies, so an undeclared return type breaks the contract.","triggerScenarios":"A handler declared to return ResponseA actually returns ResponseB (or None when a response was declared), with strict=True. Common when the handler logic has multiple return paths returning different types.","commonSituations":"A bug in the handler returning None on an error path while a response type is declared; returning a subclass whose exact type() differs; refactoring the return type without updating the annotation.","solutions":["Make every return path produce one of the declared return types.","Widen the return annotation to a Union covering all returned types, or to Any.","Set strict=False to demote to a warning (only when acceptable).","Ensure error paths raise rather than returning an undeclared type."],"exampleFix":"// before\n@message_handler\nasync def handle(self, message: Req, ctx: MessageContext) -> Resp:\n    if not ok:\n        return None   # undeclared -> ValueError\n    return Resp(...)\n// after\n@message_handler\nasync def handle(self, message: Req, ctx: MessageContext) -> Resp:\n    if not ok:\n        raise ValueError(\"not ok\")\n    return Resp(...)","handlingStrategy":"try-catch","validationCode":"from semantic_kernel.agents.runtime.core.type_helpers import AnyType\n\ndef return_in_declared_types(value, return_types) -> bool:\n    return AnyType in return_types or type(value) in return_types","typeGuard":"from typing import Any\nfrom semantic_kernel.agents.runtime.core.type_helpers import AnyType\n\ndef return_matches_declared(value: Any, return_types) -> bool:\n    return AnyType in return_types or type(value) in return_types","tryCatchPattern":"try:\n    await handler.run(message, ctx)\nexcept ValueError as e:\n    if \"Return type\" in str(e) and \"not in return types\" in str(e):\n        # fix the handler's return paths or widen the annotation\n        raise\n    raise","preventionTips":["Ensure every return path yields a declared return type.","Widen the return annotation to a Union or Any if multiple types are possible.","Raise on error paths instead of returning an undeclared type (e.g. None).","Set strict=False only if downgrading to a warning is acceptable."],"tags":["runtime","message-handler","type-mismatch","semantic-kernel"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}