{"record":{"id":"396513127c74ccbb","repo":"spring-projects/spring-ai","slug":"tool-execution-results-are-not-supported-for-bedro","errorCode":null,"errorMessage":"Tool execution results are not supported for Bedrock models","messagePattern":"Tool execution results are not supported for Bedrock models","errorType":"exception","errorClass":"java.lang.IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/MessageToPromptConverter.java","lineNumber":91,"sourceCode":"\n\t\tfinal String userMessages = messages.stream()\n\t\t\t.filter(message -> message.getMessageType() == MessageType.USER\n\t\t\t\t\t|| message.getMessageType() == MessageType.ASSISTANT)\n\t\t\t.map(this::messageToString)\n\t\t\t.collect(Collectors.joining(System.lineSeparator()));\n\n\t\t// Related to: https://github.com/spring-projects/spring-ai/issues/404\n\t\treturn systemMessages + this.lineSeparator + this.lineSeparator + userMessages + this.lineSeparator\n\t\t\t\t+ ASSISTANT_PROMPT;\n\t}\n\n\tprotected @Nullable String messageToString(Message message) {\n\t\treturn switch (message.getMessageType()) {\n\t\t\tcase SYSTEM -> message.getText();\n\t\t\tcase USER -> this.humanPrompt + \" \" + message.getText();\n\t\t\tcase ASSISTANT -> this.assistantPrompt + \" \" + message.getText();\n\t\t\tcase TOOL ->\n\t\t\t\tthrow new IllegalArgumentException(\"Tool execution results are not supported for Bedrock models\");\n\t\t};\n\n\t}\n\n}\n","sourceCodeStart":73,"sourceCodeEnd":97,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/MessageToPromptConverter.java#L73-L97","documentation":"MessageToPromptConverter converts Spring AI Message objects into a single text prompt for Titan-style Bedrock models. Bedrock models driven through this converter only support plain text prompt completion, so a Message of type TOOL (a tool/function execution result fed back to the model) cannot be represented and is rejected. The library throws IllegalArgumentException because continuing would silently drop tool output.","triggerScenarios":"Calling the Bedrock chat model with a Prompt whose message list contains a ToolResponseMessage / Message with MessageType TOOL, e.g. after a tool call round-trip with a model client that routes through messageToString.","commonSituations":"Enabling Spring AI tool/function calling with a Bedrock model (Titan) that has no native tool-calling API; reusing a prompt built for OpenAI/Anthropic (which support tool messages) against Bedrock; upgrading code to a Spring AI version where tool results are delivered as TOOL messages.","solutions":["Do not send tool result messages to Bedrock models that lack tool support; convert the tool output into a USER or ASSISTANT text message yourself before building the Prompt","Switch to a Bedrock model/client that supports native tool use (e.g. Anthropic Claude on Bedrock via its supported client)","Remove ToolResponseMessage entries from the prompt or handle tool orchestration in application code instead of via the framework"],"exampleFix":"// before\nPrompt prompt = new Prompt(List.of(userMsg, toolResponseMessage));\nbedrockChatModel.call(prompt); // throws\n// after\nMessage toolAsText = new UserMessage(\"Tool result: \" + toolResponseMessage.getResponses().get(0).responseData());\nPrompt prompt = new Prompt(List.of(userMsg, toolAsText));","handlingStrategy":"validation","validationCode":"boolean hasToolMessages = prompt.getInstructions().stream().anyMatch(m -> m.getMessageType() == MessageType.TOOL);\nif (hasToolMessages) throw new IllegalStateException(\"Bedrock model does not support TOOL messages; convert them to text first\");","typeGuard":"boolean isToolMessage(Message m) { return m.getMessageType() == MessageType.TOOL; }","tryCatchPattern":"try { model.call(prompt); } catch (IllegalArgumentException e) { if (e.getMessage().contains(\"Tool execution results\")) { /* convert tool messages to text and retry */ } else throw e; }","preventionTips":["Never send ToolResponseMessage to text-completion Bedrock models","Map tool outputs into UserMessage text manually when orchestrating tools","Check model capability docs before enabling tool calling"],"tags":["bedrock","tool-calling","unsupported-message-type","illegal-argument"],"backgroundTag":"unsupported-operation","analyzedSha":"98a7beda4f29d80a71c5837eb4053b03a93a46f7","analyzedAt":"2026-09-11T14:15:49.441Z","contentChangedAt":"2026-09-11T14:15:49.441Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}