{"record":{"id":"833e7aff96aa7976","repo":"spring-projects/spring-ai","slug":"unsupported-content-block-type-block","errorCode":null,"errorMessage":"Unsupported content block type: + block","messagePattern":"Unsupported content block type: \\+ block","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/AnthropicChatModel.java","lineNumber":1054,"sourceCode":"\t\t\t\tthinkingContents.add(AnthropicThinkingContent.redacted(redactedBlock.data()));\n\t\t\t\tMap<String, Object> redactedProperties = new HashMap<>();\n\t\t\t\tredactedProperties.put(\"data\", redactedBlock.data());\n\t\t\t\tgenerations.add(new Generation(AssistantMessage.builder().properties(redactedProperties).build(),\n\t\t\t\t\t\tgenerationMetadata));\n\t\t\t}\n\t\t\telse if (block.isWebSearchToolResult()) {\n\t\t\t\tWebSearchToolResultBlock wsBlock = block.asWebSearchToolResult();\n\t\t\t\tif (wsBlock.content().isResultBlocks()) {\n\t\t\t\t\tfor (WebSearchResultBlock r : wsBlock.content().asResultBlocks()) {\n\t\t\t\t\t\twebSearchAccumulator\n\t\t\t\t\t\t\t.add(new AnthropicWebSearchResult(r.title(), r.url(), r.pageAge().orElse(null)));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (block.isContainerUpload() || block.isServerToolUse() || block.isBashCodeExecutionToolResult()\n\t\t\t\t\t|| block.isTextEditorCodeExecutionToolResult() || block.isCodeExecutionToolResult()) {\n\t\t\t\tif (logger.isWarnEnabled()) {\n\t\t\t\t\tlogger.warn(\"Unsupported content block type: \" + block);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tgenerations.add(new Generation(buildAssistantMessage(textContent.toString(), toolCalls, thinkingContents),\n\t\t\t\tgenerationMetadata));\n\n\t\treturn generations;\n\t}\n\n\t/**\n\t * Creates chat response metadata from the Anthropic message.\n\t * @param message the Anthropic message\n\t * @param usage the usage information\n\t * @return the chat response metadata\n\t */\n\tprivate ChatResponseMetadata from(Message message, Usage usage, List<Citation> citations,\n\t\t\tList<AnthropicWebSearchResult> webSearchResults, RateLimit rateLimit) {","sourceCodeStart":1036,"sourceCodeEnd":1072,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/AnthropicChatModel.java#L1036-L1072","documentation":"A warning logged while converting Anthropic response content blocks into Spring AI generations when the block type is one the model does not map: container_upload, server_tool_use, bash_code_execution_tool_result, text_editor_code_execution_tool_result, or code_execution_tool_result. The block is skipped silently (no exception); only its content is dropped from the assistant message.","triggerScenarios":"Calling the chat model (streaming or non-streaming) with server-side tools enabled — Anthropic's code execution, bash code execution, text editor code execution, or web search container uploads — so the response contains these tool-execution block types.","commonSituations":"Enabling Anthropic's built-in code-execution / server tools via options or beta headers; upgrading to a model that returns new block types while the Spring AI mapper only knows text, thinking, tool_use and tool_result; proxies injecting server tool blocks.","solutions":["Upgrade spring-ai-anthropic to a version that maps server tool-use and code-execution blocks","Disable server-side tools (code execution etc.) in request options if their outputs are not needed","Extract needed data from the raw Anthropic response yourself before/independently of Spring AI conversion","Treat the warning as informational if you only consume text/tool-call content"],"exampleFix":"// before\nAnthropicChatOptions options = AnthropicChatOptions.builder()\n    .withToolChoices(...) // server tools enabled -> code execution blocks\n    .build();\n// after\n// remove server-side tool config or upgrade driver so blocks are mapped\nAnthropicChatOptions options = AnthropicChatOptions.builder()\n    .withModel(\"claude-sonnet-4-5\")\n    .build();","handlingStrategy":"type-guard","validationCode":"// before sending, avoid server-side tools you don't handle\nif (options.getToolCallbacks().stream().anyMatch(t -> t.getName().startsWith(\"bash\") || t.getName().startsWith(\"str_replace\"))) {\n    logger.warn(\"Server-side tool requested; response may contain unmapped blocks\");\n}","typeGuard":"boolean isMappedBlock(ContentBlock block) {\n    return block.isText() || block.isToolUse() || block.isThinking() || block.isToolResult();\n}","tryCatchPattern":"for (Generation g : response.getResults()) {\n    AssistantMessage msg = g.getOutput();\n    if (!CollectionUtils.isEmpty(msg.getToolCalls())) { ... }\n    // treat missing text as expected when server tools are in play\n}\n// note: this path is a warning, not an exception — no catch needed","preventionTips":["Do not enable Anthropic code-execution/server tools unless your spring-ai version maps them","Check the changelog of spring-ai-anthropic for new ContentBlock support before upgrading models","If you need server-tool outputs, read the raw response instead of relying on the mapped AssistantMessage","Treat missing text content as normal when server tool blocks are expected"],"tags":["anthropic","content-block","unsupported-type","spring-ai","tool-use"],"backgroundTag":"unsupported-operation","analyzedSha":"98a7beda4f29d80a71c5837eb4053b03a93a46f7","analyzedAt":"2026-09-11T14:15:49.441Z","contentChangedAt":"2026-09-11T14:15:49.441Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}