spring-projects/spring-ai · warning
Unsupported content block type: + block
Error message
Unsupported content block type: + block
What it means
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.
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
Example fix
// before
AnthropicChatOptions options = AnthropicChatOptions.builder()
.withToolChoices(...) // server tools enabled -> code execution blocks
.build();
// after
// remove server-side tool config or upgrade driver so blocks are mapped
AnthropicChatOptions options = AnthropicChatOptions.builder()
.withModel("claude-sonnet-4-5")
.build(); Defensive patterns
Strategy: type-guard
Validate before calling
// before sending, avoid server-side tools you don't handle
if (options.getToolCallbacks().stream().anyMatch(t -> t.getName().startsWith("bash") || t.getName().startsWith("str_replace"))) {
logger.warn("Server-side tool requested; response may contain unmapped blocks");
} Type guard
boolean isMappedBlock(ContentBlock block) {
return block.isText() || block.isToolUse() || block.isThinking() || block.isToolResult();
} Try / catch
for (Generation g : response.getResults()) {
AssistantMessage msg = g.getOutput();
if (!CollectionUtils.isEmpty(msg.getToolCalls())) { ... }
// treat missing text as expected when server tools are in play
}
// note: this path is a warning, not an exception — no catch needed Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Anthropic cache breakpoint limit (4) reached. Additional…
- Anthropic Citations API requires all documents to have…
- Failed to parse tool arguments JSON: + argumentsJson
- httpClientBuilderCustomizers cannot be combined with a…
- httpClientBuilderCustomizers cannot be combined with a…
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/833e7aff96aa7976.
Report an issue: GitHub.
Appendix: source
Thrown at models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/AnthropicChatModel.java:1054
thinkingContents.add(AnthropicThinkingContent.redacted(redactedBlock.data()));
Map<String, Object> redactedProperties = new HashMap<>();
redactedProperties.put("data", redactedBlock.data());
generations.add(new Generation(AssistantMessage.builder().properties(redactedProperties).build(),
generationMetadata));
}
else if (block.isWebSearchToolResult()) {
WebSearchToolResultBlock wsBlock = block.asWebSearchToolResult();
if (wsBlock.content().isResultBlocks()) {
for (WebSearchResultBlock r : wsBlock.content().asResultBlocks()) {
webSearchAccumulator
.add(new AnthropicWebSearchResult(r.title(), r.url(), r.pageAge().orElse(null)));
}
}
}
else if (block.isContainerUpload() || block.isServerToolUse() || block.isBashCodeExecutionToolResult()
|| block.isTextEditorCodeExecutionToolResult() || block.isCodeExecutionToolResult()) {
if (logger.isWarnEnabled()) {
logger.warn("Unsupported content block type: " + block);
}
}
}
generations.add(new Generation(buildAssistantMessage(textContent.toString(), toolCalls, thinkingContents),
generationMetadata));
return generations;
}
/**
* Creates chat response metadata from the Anthropic message.
* @param message the Anthropic message
* @param usage the usage information
* @return the chat response metadata
*/
private ChatResponseMetadata from(Message message, Usage usage, List<Citation> citations,
List<AnthropicWebSearchResult> webSearchResults, RateLimit rateLimit) {View on GitHub (pinned to 98a7beda4f)