microsoft/semantic-kernel · error · AgentInvokeException
Messages must be a string or a ChatMessageContent for Bedroc
Error message
Messages must be a string or a ChatMessageContent for BedrockAgent.
What it means
Raised by BedrockAgent.get_response when the messages argument is neither a str nor a ChatMessageContent. Although the type hint allows list[str | ChatMessageContent], the runtime check rejects lists — BedrockAgent expects a single user message per invocation because each invoke_agent call sends one inputText to a stateful session.
Source
Thrown at python/semantic_kernel/agents/bedrock/bedrock_agent.py:288
arguments: KernelArguments | None = None,
kernel: "Kernel | None" = None,
**kwargs,
) -> AgentResponseItem[ChatMessageContent]:
"""Get a response from the agent.
Args:
messages (str | ChatMessageContent | list[str | ChatMessageContent]): The messages.
thread (AgentThread, optional): The thread. This is used to maintain the session state in the service.
agent_alias (str, optional): The agent alias.
arguments (KernelArguments, optional): The kernel arguments to override the current arguments.
kernel (Kernel, optional): The kernel to override the current kernel.
**kwargs: Additional keyword arguments.
Returns:
A chat message content with the response.
"""
if not isinstance(messages, str) and not isinstance(messages, ChatMessageContent):
raise AgentInvokeException("Messages must be a string or a ChatMessageContent for BedrockAgent.")
thread = await self._ensure_thread_exists_with_messages(
messages=messages,
thread=thread,
construct_thread=lambda: BedrockAgentThread(bedrock_runtime_client=self.bedrock_runtime_client),
expected_type=BedrockAgentThread,
)
assert thread.id is not None # nosec
if arguments is None:
arguments = KernelArguments(**kwargs)
else:
arguments.update(kwargs)
kernel = kernel or self.kernel
arguments = self._merge_arguments(arguments)
kwargs.setdefault("streamingConfigurations", {})["streamFinalResponse"] = FalseView on GitHub (pinned to c028a0c7dc)
Solutions
- Pass a single string: await agent.get_response(message="Hello").
- Pass a single ChatMessageContent with role=USER: await agent.get_response(message=ChatMessageContent(role=AuthorRole.USER, content="Hello")).
- If you have multiple messages, concatenate them into one string or invoke the agent once per message, relying on the Bedrock session to maintain history.
- Do not pass None; always supply the user turn.
Example fix
// before
response = await agent.get_response(messages=[msg1, msg2]) # list rejected
// after
response = await agent.get_response(message="Combined: " + msg1.content + msg2.content)
# or invoke sequentially:
for msg in [msg1, msg2]:
response = await agent.get_response(message=msg, thread=thread) Defensive patterns
Strategy: type-guard
Validate before calling
from semantic_kernel.contents.chat_message_content import ChatMessageContent
def to_bedrock_message(messages) -> str | ChatMessageContent:
if isinstance(messages, (str, ChatMessageContent)):
return messages
if isinstance(messages, list) and messages:
# concatenate list into one string
parts = [m if isinstance(m, str) else m.content for m in messages]
return "\n".join(parts)
raise TypeError("BedrockAgent.get_response requires a single str or ChatMessageContent") Type guard
from semantic_kernel.contents.chat_message_content import ChatMessageContent
def is_valid_bedrock_message(messages) -> bool:
return isinstance(messages, (str, ChatMessageContent)) Try / catch
from semantic_kernel.exceptions.agent_exceptions import AgentInvokeException
try:
resp = await agent.get_response(message=msg)
except AgentInvokeException as e:
if "must be a string or a ChatMessageContent" in str(e):
resp = await agent.get_response(message=str(msg)) # coerce
else:
raise Prevention
- Always pass a single str or ChatMessageContent to BedrockAgent.get_response.
- Do not pass a list even though the type hint allows it.
- Use a wrapper to coerce lists into a single message before invoking.
When it happens
Trigger: Triggered in get_response when isinstance(messages, str) and isinstance(messages, ChatMessageContent) are both False — e.g. passing a list of messages, None (when messages param is omitted and defaults), a dict, or any other type.
Common situations: Passing a list of messages like get_response(messages=[msg1, msg2]); passing None explicitly; passing a plain dict or a ChatHistory object; migrating from an agent API that accepts lists (e.g. ChatCompletionAgent) without converting to a single message.
Related errors
- Chat message content is expected but not found in the respon
- No response from the agent.
- Failed to get a response from the agent. Please consider inc
- No file found in the response.
- The Bedrock agent requires a message to be invoked.
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/8e419d8bd0308ace.
Report an issue: GitHub.