microsoft/autogen · error · InvalidOperationException
Invalid Role
Error message
Invalid Role
What it means
ProcessTextMessage maps a TextMessage with From == null to a UserChatMessage or AssistantChatMessage based on Role. Only Role.User and Role.Assistant are handled; any other role (typically Role.System, or a custom/undefined role) with a null sender throws 'Invalid Role'.
Source
Thrown at dotnet/src/AutoGen.OpenAI/Middleware/OpenAIChatRequestMessageConnector.cs:259
private IEnumerable<ChatMessage> ProcessTextMessage(IAgent agent, TextMessage message)
{
if (message.Role == Role.System)
{
return [new SystemChatMessage(message.Content) { ParticipantName = message.From }];
}
if (agent.Name == message.From)
{
return [new AssistantChatMessage(message.Content) { ParticipantName = agent.Name }];
}
else
{
return message.From switch
{
null when message.Role == Role.User => [new UserChatMessage(message.Content)],
null when message.Role == Role.Assistant => [new AssistantChatMessage(message.Content)],
null => throw new InvalidOperationException("Invalid Role"),
_ => [new UserChatMessage(message.Content) { ParticipantName = message.From }]
};
}
}
private IEnumerable<ChatMessage> ProcessImageMessage(IAgent agent, ImageMessage message)
{
if (agent.Name == message.From)
{
// image message from assistant is not supported
throw new ArgumentException("ImageMessage is not supported when message.From is the same with agent");
}
var imageContentItem = this.CreateChatMessageImageContentItemFromImageMessage(message);
return [new UserChatMessage([imageContentItem]) { ParticipantName = message.From }];
}
private IEnumerable<ChatMessage> ProcessMultiModalMessage(IAgent agent, MultiModalMessage message)View on GitHub (pinned to 027ecf0a37)
Solutions
- Set From on the message (any non-null value) so it maps to UserChatMessage with ParticipantName.
- Use Role.User or Role.Assistant for sender-less messages instead of Role.System.
- Deliver system prompts via the agent's system instructions / SystemChatMessage at construction, not as a runtime TextMessage.
Example fix
// before var msg = new TextMessage(Role.System, "You are a helpful pirate"); // From is null // after var msg = new TextMessage(Role.System, "You are a helpful pirate", from: "system");
Defensive patterns
Strategy: validation
Validate before calling
static TextMessage CreateSafeText(Role role, string content, string? from = null)
{
if (from is null && role is not (Role.User or Role.Assistant))
throw new ArgumentException($"TextMessage with role {role} must set From.");
return new TextMessage(role, content, from);
} Try / catch
catch (InvalidOperationException ex) when (ex.Message == "Invalid Role")
{
// re-issue with explicit sender
return new TextMessage(Role.User, content, from: "system");
} Prevention
- Set From on every history message you build (system prompts included).
- Deliver system prompts through the agent's system-message construction, not runtime TextMessages.
When it happens
Trigger: Sending new TextMessage(Role.System, ...) (or Role.Custom) without setting the From field to this agent's conversation partner.
Common situations: Developers moving a system prompt from agent construction into the message history; porting code from the legacy Message type where Role.System with null From was accepted; typos in role selection.
Related errors
- Invalid message type: {m.GetType().Name}
- The method or operation is not implemented.
- Invalid message type
- Invalid return message type {message.GetType().Name}
- The content has more than one choice. Please try another inp
AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15).
Data as JSON: /api/errors/9cffa32bef1712e9.
Report an issue: GitHub.