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

  1. Pass strictMode: false when creating OpenAIChatRequestMessageConnector so unsupported messages are ignored instead of throwing.
  2. Convert or filter messages before sending: ensure ImageMessage/MultiModalMessage come from a sender different from the agent, and only send supported IMessage types.
  3. For custom message types, wrap them in MessageEnvelope<ChatMessage> (IMessage<ChatMessage>) which passes through untouched.
  4. 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

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


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