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
- Align the closure's message annotation with what is actually delivered, or register multiple closures/agents per message type.
- Narrow the agent's subscriptions so it only receives the annotated type.
- Set unknown_type_policy='ignore' to silently skip foreign types, or keep 'warn' to log-and-drop.
- 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
- Scope topic subscriptions so closure agents only receive annotated types.
- Choose unknown_type_policy deliberately: 'warn' during development, 'ignore' for mixed topics, 'error' only for strict routing.
- Test with every message type that can reach the agent before enabling 'error'.
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
- Closure must have 4 arguments
- return not found in function signature
- Message type not found
- Return type not found
- ClosureAgent must be instantiated within the context of an A
AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15).
Data as JSON: /api/errors/3eaf8aabee2975e9.
Report an issue: GitHub.