microsoft/autogen · error · InvalidOperationException
The message is not a valid message
Error message
The message is not a valid message
What it means
PrintMessageMiddleware's streaming branch keeps the last IMessage seen in the update stream (recentUpdate) and returns it; if the stream completes without yielding any IMessage instance, recentUpdate is null and it throws InvalidOperationException('The message is not a valid message'). In effect, the middleware was asked to process a streaming reply that contained zero actual messages.
Source
Thrown at dotnet/src/AutoGen.Core/Middleware/PrintMessageMiddleware.cs:37
public async Task<IMessage> InvokeAsync(MiddlewareContext context, IAgent agent, CancellationToken cancellationToken = default)
{
if (agent is IStreamingAgent streamingAgent)
{
IMessage? recentUpdate = null;
await foreach (var message in this.InvokeAsync(context, streamingAgent, cancellationToken))
{
if (message is IMessage imessage)
{
recentUpdate = imessage;
}
}
Console.WriteLine();
if (recentUpdate is not null && recentUpdate is not TextMessage)
{
Console.WriteLine(recentUpdate.FormatMessage());
}
return recentUpdate ?? throw new InvalidOperationException("The message is not a valid message");
}
else
{
var reply = await agent.GenerateReplyAsync(context.Messages, context.Options, cancellationToken);
var formattedMessages = reply.FormatMessage();
Console.WriteLine(formattedMessages);
return reply;
}
}
public async IAsyncEnumerable<IMessage> InvokeAsync(MiddlewareContext context, IStreamingAgent agent, [EnumeratorCancellation] CancellationToken cancellationToken = default)
{
IMessage? recentUpdate = null;
await foreach (var message in agent.GenerateStreamingReplyAsync(context.Messages, context.Options, cancellationToken))
{View on GitHub (pinned to 027ecf0a37)
Solutions
- Ensure the agent/stream produces at least one IMessage before routing through PrintMessageMiddleware in streaming mode.
- Check for empty input upstream and short-circuit with a sensible default (return an empty TextMessage instead of forwarding nothing).
- Reorder middleware so PrintMessageMiddleware is not downstream of a filter that can drop all messages.
- Wrap in try/catch for InvalidOperationException and treat it as an empty-reply condition (log and skip).
Example fix
// before
await foreach (var unused in agent.GenerateStreamingReplyAsync(messages)) { } // zero chunks
var reply = await printMiddleware.InvokeAsync(agent, messages, options); // throws
// after
var chunks = new List<IMessage>();
await foreach (var chunk in agent.GenerateStreamingReplyAsync(messages)) chunks.Add(chunk);
if (chunks.Count == 0) return new TextMessage(Role.Assistant, string.Empty, from: agent.Name);
var reply = await printMiddleware.InvokeAsync(agent, chunks, options); Defensive patterns
Strategy: validation
Validate before calling
var chunks = await CollectChunksAsync(agent, messages);
if (chunks.Count == 0)
return new TextMessage(Role.Assistant, string.Empty, from: agent.Name); // avoid empty-stream middleware call Try / catch
try { return await printMiddleware.InvokeAsync(agent, messages, options); }
catch (InvalidOperationException ex) when (ex.Message.Contains("not a valid message"))
{
return new TextMessage(Role.Assistant, string.Empty, from: agent.Name); // empty-reply sentinel
} Prevention
- Guard against zero-chunk streams before routing through PrintMessageMiddleware.
- Order middleware so print runs before any filter that could drop all messages.
- Treat empty completions as a distinct, logged outcome rather than letting them reach the middleware.
When it happens
Trigger: Invoking an agent through PrintMessageMiddleware in streaming mode where the update collection is empty or contains only non-IMessage items; a stream that errors/completes early before any chunk arrives; downstream middleware filtering out every message before print runs.
Common situations: Empty completions from the provider (no content chunks); unit tests passing empty message sequences; middleware pipeline ordering where an earlier middleware swallows all messages; cancellation racing the first chunk.
Related errors
- The first message is ToolCallMessage, but the update message
- FunctionMap is not available
- Invalid streaming message type {reply.GetType().Name}
- No user message found.
- No user message found.
AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15).
Data as JSON: /api/errors/f77d6243141c65d1.
Report an issue: GitHub.