microsoft/semantic-kernel · error · ValueError

Invalid arguments

Error message

Invalid arguments

What it means

Raised at the bottom of the @message_handler decorator when the first positional argument (func) is neither None nor callable. The decorator supports both bare (@message_handler) and direct (@message_handler(func)) usage; any other first argument is a misuse.

Source

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

                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")


# endregion

# region Message Handler Decorators


@experimental
@overload
def event(
    func: Callable[[AgentT, ReceivesT, MessageContext], Coroutine[Any, Any, None]],
) -> MessageHandler[AgentT, ReceivesT, None]: ...


@experimental
@overload
def event(
    func: None = None,

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Use the bare form @message_handler on the method, or keyword args for options.
  2. If passing options, use @message_handler(strict=False, match=...) without a positional func.
  3. Do not pass a string/int/object as the first positional argument.
  4. Check that any variable passed positionally is actually the method being decorated.

Example fix

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

Strategy: validation

Validate before calling

from collections.abc import Callable

def is_valid_handler_decorator_arg(func) -> bool:
    return func is None or callable(func)

Type guard

from collections.abc import Callable
from typing import Any

def is_callable_or_none(value: Any) -> bool:
    return value is None or callable(value)

Prevention

When it happens

Trigger: Calling message_handler with a non-callable first positional argument, e.g. @message_handler(some_string) or message_handler(123). Also reachable via unusual decorator stacking that passes a non-callable.

Common situations: Mistakenly passing decorator options as the first positional instead of via keyword args; misusing the decorator factory form; accidentally invoking message_handler(value) instead of message_handler()(value).

Related errors


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