microsoft/autogen · error · RuntimeError
Unexpected event type: {type(event)}
Error message
Unexpected event type: {type(event)} What it means
While tool calls execute, AssistantAgent consumes an event stream from the internal tool-execution flow and requires every item to be a BaseAgentEvent or BaseChatMessage. This error means an object of some other type (raw string, Response, tool result, etc.) was emitted into that stream, breaking the agent-chat event protocol.
Source
Thrown at python/packages/autogen-agentchat/src/autogen_agentchat/agents/_assistant_agent.py:1228
for call in function_calls
]
)
# Signal the end of streaming by putting None in the queue.
stream_queue.put_nowait(None)
return results
task = asyncio.create_task(_execute_tool_calls(current_model_result.content, stream))
while True:
event = await stream.get()
if event is None:
# End of streaming, break the loop.
break
if isinstance(event, BaseAgentEvent) or isinstance(event, BaseChatMessage):
yield event
inner_messages.append(event)
else:
raise RuntimeError(f"Unexpected event type: {type(event)}")
# Wait for all tool calls to complete.
executed_calls_and_results = await task
exec_results = [result for _, result in executed_calls_and_results]
# Yield ToolCallExecutionEvent
tool_call_result_msg = ToolCallExecutionEvent(
content=exec_results,
source=agent_name,
)
event_logger.debug(tool_call_result_msg)
await model_context.add_message(FunctionExecutionResultMessage(content=exec_results))
inner_messages.append(tool_call_result_msg)
yield tool_call_result_msg
# STEP 4C: Check for handoff
handoff_output = cls._check_and_handle_handoff(
model_result=current_model_result,View on GitHub (pinned to 027ecf0a37)
Solutions
- Make the custom tool-execution/reflection generator yield only BaseAgentEvent or BaseChatMessage instances (e.g. ToolCallExecutionEvent, ToolCallRequestEvent, TextMessage).
- Print or log type(event) at the failure point to identify exactly which object is leaking into the stream.
- Align versions: reinstall autogen-core, autogen-agentchat and autogen-ext from the same release so isinstance checks match.
Defensive patterns
Strategy: try-catch
Type guard
from autogen_agentchat.base import Response
from autogen_agentchat.messages import BaseAgentEvent, BaseChatMessage
def is_stream_event(obj) -> bool:
return isinstance(obj, (BaseAgentEvent, BaseChatMessage)) Try / catch
try:
async for msg in agent.on_messages_stream(input_msgs, ct):
handle(msg)
except RuntimeError as e:
if "Unexpected event type" in str(e):
log.error(f"Non-event object entered the tool-execution stream: {e}")
raise Prevention
- Never yield raw strings, dicts, or Response objects from custom tool-execution/reflection overrides.
- Keep autogen-core and autogen-agentchat versions aligned so isinstance checks agree.
- Add a type assertion inside custom generators before yielding.
When it happens
Trigger: Overriding or customizing AssistantAgent's tool-execution/reflection path so it yields non-event objects; mixing autogen-core / autogen-agentchat / autogen-ext versions so the stream produces types the loop does not recognize.
Common situations: Subclassed agents or custom tool-call executors that yield strings or plain dicts; package version drift after partial upgrades where event class identities diverge.
Related errors
- Invalid chunk type: {type(chunk)}
- Please set OPENAI_API_KEY environment variable.
- Failed to deserialize response
- Value was null.
- Unable to convert "{value}" to enum {typeToConvert}.
AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15).
Data as JSON: /api/errors/cef3a8d065689bd3.
Report an issue: GitHub.