microsoft/semantic-kernel · error · AssertionError

Message type not found

Error message

Message type not found

What it means

Raised by the @message_handler decorator when the 'message' parameter has a type hint that get_types cannot resolve into concrete types. get_types returns None for typing special forms (e.g. a bare TypeVar, a ParamSpec, or a forward reference that cannot be evaluated), so the handler cannot be routed by message type.

Source

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

            is applied in alphabetical order of the handlers and the first matching handler will be called while the
            rest are skipped. If `None`, the first handler in alphabetical order matching the same message type will
            be called.
    """

    def decorator(
        func: Callable[[AgentT, ReceivesT, MessageContext], Coroutine[Any, Any, ProducesT]],
    ) -> MessageHandler[AgentT, ReceivesT, ProducesT]:
        type_hints = get_type_hints(func)
        if "message" not in type_hints:
            raise AssertionError("message parameter not found in function signature")

        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"])
        if target_types is None:
            raise AssertionError("Message type not found")

        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:

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Annotate message with a concrete class, a Union of classes, Optional[...], or Any.
  2. Ensure the referenced message class is imported at runtime (not only under TYPE_CHECKING).
  3. Replace TypeVar/forward-ref annotations with the actual message class.
  4. Run get_type_hints on the method manually to reproduce the resolution failure.

Example fix

// before
T = TypeVar("T")
@message_handler
async def handle(self, message: T, ctx: MessageContext) -> None: ...
// after
@message_handler
async def handle(self, message: MyMsg, ctx: MessageContext) -> None: ...
Defensive patterns

Strategy: validation

Validate before calling

from typing import get_type_hints
from semantic_kernel.agents.runtime.core.type_helpers import get_types

def message_type_resolves(func) -> bool:
    hints = get_type_hints(func)
    return "message" in hints and get_types(hints["message"]) is not None

Type guard

from typing import get_type_hints, Callable
from semantic_kernel.agents.runtime.core.type_helpers import get_types

def has_resolvable_message_type(func: Callable) -> bool:
    try:
        hints = get_type_hints(func)
        return get_types(hints.get("message")) is not None
    except Exception:
        return False

Prevention

When it happens

Trigger: Annotating message as an unbound TypeVar, a string forward reference that get_type_hints cannot resolve, Any (returns AnyType, fine) vs an unresolvable special form, or a ParamSpec/Concatenate construct.

Common situations: Using a generic TypeVar for the message type; referencing a message class that is imported lazily or only under TYPE_CHECKING; typos in the type name with from __future__ import annotations.

Related errors


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