microsoft/autogen · error · ArgumentException

Invalid message type

Error message

Invalid message type

What it means

SemanticKernelChatCompletionAgent.ProcessMessage only accepts IMessage<ChatMessageContent>. Any other IMessage implementation (TextMessage, ImageMessage, MessageEnvelope<T> with T != ChatMessageContent) throws ArgumentException 'Invalid message type' while building the ChatHistory.

Source

Thrown at dotnet/src/AutoGen.SemanticKernel/SemanticKernelChatCompletionAgent.cs:49

            .InvokeAsync(agentThread, cancellationToken: cancellationToken)
            .ToArrayAsync(cancellationToken: cancellationToken);

        return reply.Length > 1
            ? throw new InvalidOperationException("ResultsPerPrompt greater than 1 is not supported in this semantic kernel agent")
            : new MessageEnvelope<ChatMessageContent>(reply[0], from: this.Name);
    }

    private ChatHistory BuildChatHistory(IEnumerable<IMessage> messages)
    {
        return new ChatHistory(ProcessMessage(messages));
    }

    private IEnumerable<ChatMessageContent> ProcessMessage(IEnumerable<IMessage> messages)
    {
        return messages.Select(m => m switch
        {
            IMessage<ChatMessageContent> cmc => cmc.Content,
            _ => throw new ArgumentException("Invalid message type")
        });
    }
}

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. Convert messages to MessageEnvelope<ChatMessageContent> before calling GenerateReplyAsync
  2. Add the SemanticKernelChatMessageContentConnector middleware to the pipeline to translate TextMessage/ImageMessage automatically
  3. Filter/transform the message list with a helper that maps each message to ChatMessageContent

Example fix

// before
var msgs = new[] { new TextMessage(Role.User, "hi") };
await adapter.GenerateReplyAsync(msgs);

// after
var msgs = new[]
{
    new MessageEnvelope<ChatMessageContent>(new ChatMessageContent(AuthorRole.User, "hi"))
};
await adapter.GenerateReplyAsync(msgs);
Defensive patterns

Strategy: type-guard

Validate before calling

var unsupported = messages.Where(m => m is not IMessage<ChatMessageContent>).Select(m => m.GetType().Name).ToList();
if (unsupported.Count > 0) throw new InvalidOperationException($"Convert first: {string.Join(",", unsupported)}");

Type guard

static bool IsChatMessageContentEnvelope(IMessage m) => m is IMessage<ChatMessageContent>;

Try / catch

try { await adapter.GenerateReplyAsync(messages); }
catch (ArgumentException ex) when (ex.Message == "Invalid message type")
{
    var converted = messages.Select(m => m switch
    {
        IMessage<ChatMessageContent> c => c,
        _ => new MessageEnvelope<ChatMessageContent>(new ChatMessageContent(AuthorRole.User, m.GetContent() ?? ""))
    });
    await adapter.GenerateReplyAsync(converted);
}

Prevention

When it happens

Trigger: Passing TextMessage or any non-ChatMessageContent message to GenerateReplyAsync on the SemanticKernelChatCompletionAgent adapter.

Common situations: Feeding history produced by AutoGen core or OpenAI agents into a SemanticKernel-backed agent, or hand-assembling history with the convenient TextMessage constructors.

Related errors


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