microsoft/autogen · error · InvalidOperationException
The recent update is not a TextMessage
Error message
The recent update is not a TextMessage
What it means
Thrown by PrintMessageMiddleware while relaying a streaming reply. The middleware folds streaming chunks into one accumulated message; when a TextMessageUpdate arrives and the message accumulated so far (recentUpdate) is not null and not a TextMessage, it cannot append text to it (e.g. a ToolCallMessage was accumulated first) and throws InvalidOperationException.
Source
Thrown at dotnet/src/AutoGen.Core/Middleware/PrintMessageMiddleware.cs:77
{
// Print from: xxx
Console.WriteLine($"from: {textMessageUpdate.From}");
recentUpdate = new TextMessage(textMessageUpdate);
Console.Write(textMessageUpdate.Content);
yield return message;
}
else if (recentUpdate is TextMessage recentTextMessage)
{
// Print the content of the message
Console.Write(textMessageUpdate.Content);
recentTextMessage.Update(textMessageUpdate);
yield return recentTextMessage;
}
else
{
throw new InvalidOperationException("The recent update is not a TextMessage");
}
}
else if (message is ToolCallMessageUpdate toolCallUpdate)
{
if (recentUpdate is null)
{
recentUpdate = new ToolCallMessage(toolCallUpdate);
yield return message;
}
else if (recentUpdate is ToolCallMessage recentToolCallMessage)
{
recentToolCallMessage.Update(toolCallUpdate);
yield return message;
}
else
{View on GitHub (pinned to 027ecf0a37)
Solutions
- Fix the streaming agent so one stream contains only one kind of update (all TextMessageUpdate or all ToolCallMessageUpdate), not interleaved types
- If you control the agent, start the stream with the text updates before emitting any complete non-text IMessage
- Remove or reorder PrintMessageMiddleware in the agent's middleware chain if you must interleave heterogeneous messages
- Catch InvalidOperationException around the streaming enumeration only as a last resort, since the console printout will already be partially written
Example fix
// before: agent yields ToolCallMessageUpdate, then TextMessageUpdate in the same stream // after: yield text updates first, or split into separate replies await foreach (var update in textUpdates) yield return update; // only TextMessageUpdate in this stream
Defensive patterns
Strategy: validation
Validate before calling
// Before consuming a stream through PrintMessageMiddleware, verify homogeneous update types
var types = new HashSet<Type>();
await foreach (var m in agent.GenerateStreamingReplyAsync(msgs, ct)) types.Add(m.GetType());
if (types.Count > 1 && types.Contains(typeof(TextMessageUpdate)))
throw new InvalidOperationException("Stream mixes text updates with other message types"); Type guard
static bool IsTextUpdateStream(IEnumerable<IMessage> replayed) =>
replayed.All(m => m is TextMessageUpdate or TextMessage); Try / catch
try { await foreach (var m in printingAgent.GenerateStreamingReplyAsync(msgs, ct)) { /* ... */ } }
catch (InvalidOperationException e) when (e.Message.Contains("not a TextMessage"))
{ /* fall back to non-streaming call */ } Prevention
- Keep one update type per streaming reply in custom IStreamingAgent implementations
- Test custom streaming agents with PrintMessageMiddleware enabled
When it happens
Trigger: An IStreamingAgent's GenerateStreamingReplyAsync yields a ToolCallMessageUpdate (or any non-text IMessage) first, then yields a TextMessageUpdate afterwards; the middleware's else branch at PrintMessageMiddleware.cs:77 fires because recentUpdate is a ToolCallMessage, not a TextMessage.
Common situations: Agents that emit tool-call chunks followed by text chunks in the same stream, custom agents mixing update types in one streaming response, or middleware pipelines that inject intermediate non-update messages before text deltas.
Related errors
- The first message is ToolCallMessage, but the update message
- The message is not a valid message
- The recent update is not a ToolCallMessage
- Unsupported message type: {reply.GetType()}
- Invalid streaming message type {reply.GetType().Name}
AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15).
Data as JSON: /api/errors/be6d7473bbcfeb3e.
Report an issue: GitHub.