{"record":{"id":"8e419d8bd0308ace","repo":"microsoft/semantic-kernel","slug":"messages-must-be-a-string-or-a-chatmessagecontent","errorCode":null,"errorMessage":"Messages must be a string or a ChatMessageContent for BedrockAgent.","messagePattern":"Messages must be a string or a ChatMessageContent for BedrockAgent\\.","errorType":"exception","errorClass":"AgentInvokeException","httpStatus":null,"severity":"error","filePath":"python/semantic_kernel/agents/bedrock/bedrock_agent.py","lineNumber":288,"sourceCode":"        arguments: KernelArguments | None = None,\n        kernel: \"Kernel | None\" = None,\n        **kwargs,\n    ) -> AgentResponseItem[ChatMessageContent]:\n        \"\"\"Get a response from the agent.\n\n        Args:\n            messages (str | ChatMessageContent | list[str | ChatMessageContent]): The messages.\n            thread (AgentThread, optional): The thread. This is used to maintain the session state in the service.\n            agent_alias (str, optional): The agent alias.\n            arguments (KernelArguments, optional): The kernel arguments to override the current arguments.\n            kernel (Kernel, optional): The kernel to override the current kernel.\n            **kwargs: Additional keyword arguments.\n\n        Returns:\n            A chat message content with the response.\n        \"\"\"\n        if not isinstance(messages, str) and not isinstance(messages, ChatMessageContent):\n            raise AgentInvokeException(\"Messages must be a string or a ChatMessageContent for BedrockAgent.\")\n\n        thread = await self._ensure_thread_exists_with_messages(\n            messages=messages,\n            thread=thread,\n            construct_thread=lambda: BedrockAgentThread(bedrock_runtime_client=self.bedrock_runtime_client),\n            expected_type=BedrockAgentThread,\n        )\n        assert thread.id is not None  # nosec\n\n        if arguments is None:\n            arguments = KernelArguments(**kwargs)\n        else:\n            arguments.update(kwargs)\n\n        kernel = kernel or self.kernel\n        arguments = self._merge_arguments(arguments)\n\n        kwargs.setdefault(\"streamingConfigurations\", {})[\"streamFinalResponse\"] = False","sourceCodeStart":270,"sourceCodeEnd":306,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/python/semantic_kernel/agents/bedrock/bedrock_agent.py#L270-L306","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nresponse = await agent.get_response(messages=[msg1, msg2])  # list rejected\n\n// after\nresponse = await agent.get_response(message=\"Combined: \" + msg1.content + msg2.content)\n# or invoke sequentially:\nfor msg in [msg1, msg2]:\n    response = await agent.get_response(message=msg, thread=thread)","handlingStrategy":"type-guard","validationCode":"from semantic_kernel.contents.chat_message_content import ChatMessageContent\n\ndef to_bedrock_message(messages) -> str | ChatMessageContent:\n    if isinstance(messages, (str, ChatMessageContent)):\n        return messages\n    if isinstance(messages, list) and messages:\n        # concatenate list into one string\n        parts = [m if isinstance(m, str) else m.content for m in messages]\n        return \"\\n\".join(parts)\n    raise TypeError(\"BedrockAgent.get_response requires a single str or ChatMessageContent\")","typeGuard":"from semantic_kernel.contents.chat_message_content import ChatMessageContent\n\ndef is_valid_bedrock_message(messages) -> bool:\n    return isinstance(messages, (str, ChatMessageContent))","tryCatchPattern":"from semantic_kernel.exceptions.agent_exceptions import AgentInvokeException\n\ntry:\n    resp = await agent.get_response(message=msg)\nexcept AgentInvokeException as e:\n    if \"must be a string or a ChatMessageContent\" in str(e):\n        resp = await agent.get_response(message=str(msg))  # coerce\n    else:\n        raise","preventionTips":["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."],"tags":["bedrock","input-validation","messages","get-response","agent-invoke"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}