microsoft/semantic-kernel · error · InvalidOperationException
Message content cannot be null.
Error message
Message content cannot be null.
What it means
Thrown by BedrockAgentChannel while building the Bedrock session-state conversation history from the channel's message backlog. For every message except the last (which is sent separately), Content must be non-null. A null Content breaks the Bedrock message model, so InvalidOperationException is thrown. Note this runs over this._history, i.e., the accumulated channel history, not just the input.
Source
Thrown at dotnet/src/Agents/Bedrock/BedrockAgentChannel.cs:223
}
private SessionState ParseHistoryToSessionState()
{
SessionState sessionState = new();
// We don't take the last message as it needs to be sent separately in another parameter.
if (this._history.Count > 1)
{
sessionState.ConversationHistory = new()
{
Messages = []
};
foreach (var message in this._history.Take(this._history.Count - 1))
{
if (message.Content is null)
{
throw new InvalidOperationException("Message content cannot be null.");
}
if (message.Role != AuthorRole.Assistant && message.Role != AuthorRole.User)
{
throw new InvalidOperationException("Message role must be either Assistant or User.");
}
sessionState.ConversationHistory.Messages.Add(new()
{
Role = message.Role == AuthorRole.Assistant
? Amazon.BedrockAgentRuntime.ConversationRole.Assistant
: Amazon.BedrockAgentRuntime.ConversationRole.User,
Content = [
new Amazon.BedrockAgentRuntime.Model.ContentBlock()
{
Text = message.Content,
},
],
});View on GitHub (pinned to c028a0c7dc)
Solutions
- Ensure every message added to the channel history has non-null Content (use string.Empty rather than null).
- Filter out metadata-only messages before they enter the Bedrock channel history.
- If converting from another provider, default null Content to an empty string.
Example fix
// before history.Add(new ChatMessageContent(AuthorRole.Assistant, content: null)); // -> throws 179 // after history.Add(new ChatMessageContent(AuthorRole.Assistant, content: "") );
Defensive patterns
Strategy: validation
Validate before calling
foreach (var m in history.Take(history.Count - 1))
{
if (m.Content is null)
throw new InvalidOperationException($"Message (role {m.Role}) has null Content; use string.Empty.");
} Type guard
static bool HistoryHasNoNullContent(IReadOnlyList<ChatMessageContent> h) =>
h.Take(h.Count - 1).All(m => m.Content is not null); Try / catch
try { /* invoke bedrock agent */ }
catch (InvalidOperationException ex) when (ex.Message.Contains("Message content cannot be null"))
{ /* replace null Content with string.Empty in the channel history */ } Prevention
- Never add a ChatMessageContent with null Content to Bedrock channel history; use string.Empty.
- Filter out metadata-only/function-step messages before they enter the history.
- Default null Content to empty string when converting from other providers.
When it happens
Trigger: The agent channel history contains a ChatMessageContent whose Content is null (e.g., a message carrying only function-call metadata with no text, or a placeholder). This is checked before role validation in the same loop.
Common situations: A tool-call or function-step message with null Content was added to the channel history; a deserialized/round-tripped message lost its content; an empty assistant ack got persisted.
Related errors
- The Bedrock agent requires a message to be invoked.
- The streaming configuration must be null for non-streaming r
- The streaming configuration must have StreamFinalResponse se
- Bedrock agents must be invoked with a user message
- Invalid role: {authorRole}
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/abeef5df7770c4de.
Report an issue: GitHub.