microsoft/autogen · error · InvalidOperationException
Invalid message type: {m.GetType().Name}
Error message
Invalid message type: {m.GetType().Name} What it means
ProcessIncomingMessages maps each incoming IMessage to OpenAI ChatMessages. When strictMode is true and the message matches none of the supported patterns (TextMessage, ImageMessage from others, MultiModalMessage from others, ToolCallMessage from self, ToolCallResultMessage, AggregateMessage), it throws this exception. In non-strict mode unknown messages are silently skipped.
Source
Thrown at dotnet/src/AutoGen.OpenAI/Middleware/OpenAIChatRequestMessageConnector.cs:227
{
return messages.SelectMany<IMessage, IMessage>(m =>
{
if (m is IMessage<ChatMessage> crm)
{
return [crm];
}
else
{
var chatRequestMessages = m switch
{
TextMessage textMessage => ProcessTextMessage(agent, textMessage),
ImageMessage imageMessage when (imageMessage.From is null || imageMessage.From != agent.Name) => ProcessImageMessage(agent, imageMessage),
MultiModalMessage multiModalMessage when (multiModalMessage.From is null || multiModalMessage.From != agent.Name) => ProcessMultiModalMessage(agent, multiModalMessage),
ToolCallMessage toolCallMessage when (toolCallMessage.From is null || toolCallMessage.From == agent.Name) => ProcessToolCallMessage(agent, toolCallMessage),
ToolCallResultMessage toolCallResultMessage => ProcessToolCallResultMessage(toolCallResultMessage),
AggregateMessage<ToolCallMessage, ToolCallResultMessage> aggregateMessage => ProcessFunctionCallMiddlewareMessage(agent, aggregateMessage),
_ when strictMode is false => [],
_ => throw new InvalidOperationException($"Invalid message type: {m.GetType().Name}"),
};
if (chatRequestMessages.Any())
{
return chatRequestMessages.Select(cm => MessageEnvelope.Create(cm, m.From));
}
else
{
return [m];
}
}
});
}
private IEnumerable<ChatMessage> ProcessTextMessage(IAgent agent, TextMessage message)
{
if (message.Role == Role.System)
{View on GitHub (pinned to 027ecf0a37)
Solutions
- Pass strictMode: false when creating OpenAIChatRequestMessageConnector so unsupported messages are ignored instead of throwing.
- Convert or filter messages before sending: ensure ImageMessage/MultiModalMessage come from a sender different from the agent, and only send supported IMessage types.
- For custom message types, wrap them in MessageEnvelope<ChatMessage> (IMessage<ChatMessage>) which passes through untouched.
- Route ToolCallMessage only to the agent that produced it (message.From must equal agent.Name).
Example fix
// before var connector = new OpenAIChatRequestMessageConnector(strictMode: true); agent.SendAsync(new ImageMessage(Role.Assistant, url, from: agent.Name)); // unsupported in strict mode // after var connector = new OpenAIChatRequestMessageConnector(strictMode: false); // or set the sender correctly: agent.SendAsync(new ImageMessage(Role.User, url, from: "user-1"));
Defensive patterns
Strategy: validation
Validate before calling
// Reject unsupported messages before strict-mode dispatch
static bool IsSupportedByOpenAIConnector(IMessage m, string agentName) => m switch
{
TextMessage => true,
ImageMessage img => img.From != agentName,
MultiModalMessage mm => mm.From != agentName,
ToolCallMessage tc => tc.From is null || tc.From == agentName,
ToolCallResultMessage => true,
AggregateMessage<ToolCallMessage, ToolCallResultMessage> => true,
IMessage<ChatMessage> => true,
_ => false,
}; Type guard
static bool IsSupportedByOpenAIConnector(IMessage m, string agentName) => m switch
{
TextMessage => true,
ImageMessage img => img.From != agentName,
MultiModalMessage mm => mm.From != agentName,
ToolCallMessage tc => tc.From is null || tc.From == agentName,
ToolCallResultMessage => true,
AggregateMessage<ToolCallMessage, ToolCallResultMessage> => true,
IMessage<ChatMessage> => true,
_ => false,
}; Try / catch
catch (InvalidOperationException ex) when (ex.Message.StartsWith("Invalid message type"))
{
logger.LogError("Unsupported message {Type}; enable non-strict mode or convert it", offendingType);
throw;
} Prevention
- Default to strictMode: false unless you explicitly want fail-fast behavior.
- Centralize message construction so only connector-supported types enter agent calls.
- Wrap custom payloads in MessageEnvelope.Create(chatMessage) which the connector passes through.
When it happens
Trigger: Constructing the connector with strictMode: true and feeding it a message type it does not handle — e.g. an ImageMessage whose From equals the agent name (its guard clause excludes it from the ImageMessage arm), or a custom IMessage implementation.
Common situations: Group-chat orchestration where an agent receives another agent's ImageMessage; custom message classes; enabling strict mode during hardening and discovering previously-dropped messages.
Related errors
- Invalid return message type {message.GetType().Name}
- Invalid Role
- The method or operation is not implemented.
- Invalid return message type {message.GetType().Name}
- Invalid message type: {m.GetType().Name}
AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15).
Data as JSON: /api/errors/53d881b9925c0f9f.
Report an issue: GitHub.