microsoft/semantic-kernel · error · InvalidOperationException
Bedrock agents must be invoked with a user message
Error message
Bedrock agents must be invoked with a user message
What it means
Thrown by BedrockAgent.ExtractUserMessage when the message's role is not AuthorRole.User. Bedrock agents expect the final/invoking message to be a user message; assistant or system messages in that slot are rejected. This validates the last message before sending it as the agent input.
Source
Thrown at dotnet/src/Agents/Bedrock/BedrockAgent.cs:550
string agentAlias = WorkingDraftAgentAlias;
bool enableTrace = false;
if (options is BedrockAgentInvokeOptions bedrockOption)
{
agentAlias = bedrockOption.AgentAliasId ?? WorkingDraftAgentAlias;
enableTrace = bedrockOption.EnableTrace;
}
var invokeRequest = createRequest();
invokeRequest.AgentAliasId = agentAlias;
invokeRequest.EnableTrace = enableTrace;
return invokeRequest;
}
private string ExtractUserMessage(ChatMessageContent chatMessageContent)
{
if (!chatMessageContent.Role.Equals(AuthorRole.User))
{
throw new InvalidOperationException("Bedrock agents must be invoked with a user message");
}
return chatMessageContent.Content ?? "";
}
private SessionState ExtractSessionState(ICollection<ChatMessageContent> messages)
{
// If there is more than one message provided, add all but the last message to the session state
SessionState sessionState = new();
if (messages.Count > 1)
{
List<Amazon.BedrockAgentRuntime.Model.Message> messageHistory = [];
for (int i = 0; i < messages.Count - 1; i++)
{
var currentMessage = messages.ElementAt(i);
messageHistory.Add(this.ToBedrockMessage(currentMessage));
}
View on GitHub (pinned to c028a0c7dc)
Solutions
- Ensure the last message in the collection has Role == AuthorRole.User.
- If the latest turn is an assistant reply, append a user turn (even a continuation prompt) before invoking.
Example fix
// before
var messages = new List<ChatMessageContent>
{
new(AuthorRole.User, "hi"),
new(AuthorRole.Assistant, "hello!"), // last is assistant -> throws 177
};
await agent.InvokeAsync(messages);
// after
messages.Add(new(AuthorRole.User, "tell me more"));
await agent.InvokeAsync(messages); Defensive patterns
Strategy: type-guard
Validate before calling
var last = messages.Last();
if (!last.Role.Equals(AuthorRole.User))
throw new InvalidOperationException("The final message must be a user message for Bedrock agents."); Type guard
static bool LastIsUser(ICollection<ChatMessageContent> m) =>
m.Count > 0 && m.Last().Role.Equals(AuthorRole.User); Try / catch
try { await agent.InvokeAsync(messages); }
catch (InvalidOperationException ex) when (ex.Message.Contains("user message"))
{ /* append a user message as the last entry and retry */ } Prevention
- Ensure the last message has AuthorRole.User before invoking.
- Append a user continuation prompt if the latest turn is an assistant reply.
When it happens
Trigger: The message passed as the primary input to ExtractUserMessage has Role equal to Assistant, System, Tool, or anything other than User.
Common situations: Caller appended an assistant follow-up as the last message by mistake; message history ordering put a non-user message last; tool/result message placed in the user slot.
Related errors
- Invalid role: {authorRole}
- 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
- Message content cannot be null.
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/4cd278555d47d743.
Report an issue: GitHub.