microsoft/autogen · error · ArgumentException
Invalid message type
Error message
Invalid message type
What it means
SemanticKernelAgent.BuildChatHistory calls ProcessMessage, which pattern-matches each IMessage against IMessage<ChatMessageContent> only. Anything else — TextMessage, ImageMessage, MessageEnvelope of another type, plain Message — throws ArgumentException with 'Invalid message type'.
Source
Thrown at dotnet/src/AutoGen.SemanticKernel/SemanticKernelAgent.cs:134
MaxTokens = options?.MaxToken ?? 1024,
StopSequences = options?.StopSequence,
ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions,
};
}
private IChatCompletionService GetChatCompletionService()
{
return string.IsNullOrEmpty(_modelServiceId)
? _kernel.GetRequiredService<IChatCompletionService>()
: _kernel.GetRequiredService<IChatCompletionService>(_modelServiceId);
}
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
- Wrap every message in MessageEnvelope<ChatMessageContent>, e.g. new MessageEnvelope<ChatMessageContent>(new ChatMessageContent(AuthorRole.User, text))
- Use the provided SemanticKernelChatMessageContentConnector middleware, which converts TextMessage and other common types into ChatMessageContent before the agent sees them
- Check each message with 'is IMessage<ChatMessageContent>' before sending and convert the ones that fail
Example fix
// before
var messages = new List<IMessage> { new TextMessage(Role.User, "hello") };
await skAgent.GenerateReplyAsync(messages);
// after
var messages = new List<IMessage>
{
new MessageEnvelope<ChatMessageContent>(new ChatMessageContent(AuthorRole.User, "hello"))
};
await skAgent.GenerateReplyAsync(messages); Defensive patterns
Strategy: type-guard
Validate before calling
var invalid = messages.Where(m => m is not IMessage<ChatMessageContent>).ToList();
if (invalid.Count > 0)
throw new InvalidOperationException($"Non-ChatMessageContent messages: {string.Join(",", invalid.Select(m => m.GetType().Name))}"); Type guard
static IMessage<ChatMessageContent>? AsChatMessageContent(IMessage m) => m as IMessage<ChatMessageContent>; // usage: messages.Select(AsChatMessageContent).Where(m => m is not null)
Try / catch
try { await skAgent.GenerateReplyAsync(messages); }
catch (ArgumentException ex) when (ex.Message == "Invalid message type")
{
var converted = messages.Select(m => new MessageEnvelope<ChatMessageContent>(
new ChatMessageContent(AuthorRole.User, m.GetContent()?.ToString() ?? string.Empty)));
await skAgent.GenerateReplyAsync(converted); // fallback conversion retry
} Prevention
- Adopt SemanticKernelChatMessageContentConnector middleware so TextMessage converts automatically
- Build SK agent history exclusively with MessageEnvelope<ChatMessageContent>
- Write a helper ToChatMessageContent(IMessage) and route every message through it
When it happens
Trigger: Passing TextMessage/IMessage<TextContent>, ImageMessage, or any non-ChatMessageContent envelope to SemanticKernelAgent.GenerateReplyAsync/GenerateStreamingReplyAsync.
Common situations: Mixing messages produced by AutoGen core agents (which emit TextMessage) with a SemanticKernel agent, or building chat history manually with the convenience TextMessage type instead of wrapping ChatMessageContent.
Related errors
- Invalid message type
- Unsupported message type {m.GetType()}
- Please set OPENAI_API_KEY environment variable.
- Missing parameter type for {parameterName}
- Missing required parameter: {parameterName}
AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15).
Data as JSON: /api/errors/799f2a16469c133f.
Report an issue: GitHub.