microsoft/semantic-kernel · error · ValueError

Return type not in return types

Error message

Return type {type(return_value)} not in return types {return_types}

What it means

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.

Solutions

  1. Make every return path produce one of the declared return types.
  2. Widen the return annotation to a Union covering all returned types, or to Any.
  3. Set strict=False to demote to a warning (only when acceptable).
  4. Ensure error paths raise rather than returning an undeclared type.

Example fix

// before
@message_handler
async def handle(self, message: Req, ctx: MessageContext) -> Resp:
    if not ok:
        return None   # undeclared -> ValueError
    return Resp(...)
// after
@message_handler
async def handle(self, message: Req, ctx: MessageContext) -> Resp:
    if not ok:
        raise ValueError("not ok")
    return Resp(...)
Defensive patterns

Strategy: try-catch

Validate before calling

from semantic_kernel.agents.runtime.core.type_helpers import AnyType

def return_in_declared_types(value, return_types) -> bool:
    return AnyType in return_types or type(value) in return_types

Type guard

from typing import Any
from semantic_kernel.agents.runtime.core.type_helpers import AnyType

def return_matches_declared(value: Any, return_types) -> bool:
    return AnyType in return_types or type(value) in return_types

Try / catch

try:
    await handler.run(message, ctx)
except ValueError as e:
    if "Return type" in str(e) and "not in return types" in str(e):
        # fix the handler's return paths or widen the annotation
        raise
    raise

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13). Data as JSON: /api/errors/2d7e1dc69b0016cb. Report an issue: GitHub.

Appendix: source

Thrown at python/semantic_kernel/agents/runtime/core/routed_agent.py:160

        return_types = get_types(type_hints["return"])

        if return_types is None:
            raise AssertionError("Return type not found")

        # Convert target_types to list and stash

        @wraps(func)
        async def wrapper(self: AgentT, message: ReceivesT, ctx: MessageContext) -> ProducesT:
            if type(message) not in target_types:
                if strict:
                    raise CantHandleException(f"Message type {type(message)} not in target types {target_types}")
                logger.warning(f"Message type {type(message)} not in target types {target_types}")

            return_value = await func(self, message, ctx)

            if AnyType not in return_types and type(return_value) not in return_types:
                if strict:
                    raise ValueError(f"Return type {type(return_value)} not in return types {return_types}")
                logger.warning(f"Return type {type(return_value)} not in return types {return_types}")

            return return_value

        wrapper_handler = cast(MessageHandler[AgentT, ReceivesT, ProducesT], wrapper)
        wrapper_handler.target_types = list(target_types)
        wrapper_handler.produces_types = list(return_types)
        wrapper_handler.is_message_handler = True
        wrapper_handler.router = match or (lambda _message, _ctx: True)

        return wrapper_handler

    if func is None and not callable(func):
        return decorator
    if callable(func):
        return decorator(func)
    raise ValueError("Invalid arguments")

View on GitHub (pinned to c028a0c7dc)