microsoft/autogen · error · CantHandleException

Message type {type(message)} not in target types {self._expe

Error message

Message type {type(message)} not in target types {self._expected_types} of {self.id}. Set unknown_type_policy to 'warn' to suppress this exception, or 'ignore' to suppress this warning.

What it means

In on_message_impl, if the delivered message's concrete type is not among the types derived from the closure's message annotation, behavior depends on unknown_type_policy: 'error' raises CantHandleException, 'warn' emits a warning and drops the message (returns None), 'ignore' silently proceeds. Note the exception text is self-inconsistent: it says set policy to 'warn' to suppress the exception — the actual escaping fix is 'ignore'.

Source

Thrown at python/packages/autogen-core/src/autogen_core/_closure_agent.py:127

    @property
    def id(self) -> AgentId:
        return self._id

    @property
    def runtime(self) -> AgentRuntime:
        return self._runtime

    async def on_message_impl(self, message: Any, ctx: MessageContext) -> Any:
        if type(message) not in self._expected_types:
            if self._unknown_type_policy == "warn":
                warnings.warn(
                    f"Message type {type(message)} not in target types {self._expected_types} of {self.id}. Set unknown_type_policy to 'error' to raise an exception, or 'ignore' to suppress this warning.",
                    stacklevel=1,
                )
                return None
            elif self._unknown_type_policy == "error":
                raise CantHandleException(
                    f"Message type {type(message)} not in target types {self._expected_types} of {self.id}. Set unknown_type_policy to 'warn' to suppress this exception, or 'ignore' to suppress this warning."
                )

        return await self._closure(self, message, ctx)

    async def save_state(self) -> Mapping[str, Any]:
        """Closure agents do not have state. So this method always returns an empty dictionary."""
        return {}

    async def load_state(self, state: Mapping[str, Any]) -> None:
        """Closure agents do not have state. So this method does nothing."""
        pass

    @classmethod
    async def register_closure(
        cls,
        runtime: AgentRuntime,
        type: str,

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. Align the closure's message annotation with what is actually delivered, or register multiple closures/agents per message type.
  2. Narrow the agent's subscriptions so it only receives the annotated type.
  3. Set unknown_type_policy='ignore' to silently skip foreign types, or keep 'warn' to log-and-drop.
  4. If 'error' is intentional, fix the publisher/routing so the right type reaches this agent.

Example fix

# before
await ClosureAgent.register(
    runtime, "worker", lambda: ClosureAgent("d", handler, unknown_type_policy="error")
)
# handler annotated for MsgA but topic also carries MsgB -> CantHandleException

# after
async def handler(agent: ClosureContext, message: MsgA, ctx: MessageContext) -> None: ...
await ClosureAgent.register(
    runtime, "worker_a", lambda: ClosureAgent("d", handler, unknown_type_policy="ignore")
)
Defensive patterns

Strategy: fallback

Validate before calling

if unknown_type_policy == "error" and type(msg) not in expected_types:
    # route to the correct handler or drop before it raises
    logging.warning("unexpected %s for closure", type(msg))
    return

Type guard

def is_handled_message(msg: object, expected: tuple[type, ...]) -> TypeGuard[Any]:
    return type(msg) in expected

Try / catch

from autogen_core.exceptions import CantHandleException

try:
    await closure_agent.handle_message(msg, ctx)
except CantHandleException as e:
    if "not in target types" in str(e):
        logging.warning("dropped foreign message %s", type(msg))
    else:
        raise

Prevention

When it happens

Trigger: A closure annotated for message: MsgA receives MsgB (e.g. broadcast/publish to a topic multiple closure agents subscribe to); deserialization producing a different concrete class than annotated; unknown_type_policy='error' (the default is 'warn').

Common situations: Topic subscriptions shared by heterogeneous agents; version skew where a peer sends an upgraded message type; policy set to 'error' globally to catch routing bugs, then hit by an intentional broadcast.

Related errors


AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15). Data as JSON: /api/errors/3eaf8aabee2975e9. Report an issue: GitHub.