spring-projects/spring-ai · error · IllegalArgumentException
Unsupported media data type: . Expected byte[] or String.
Error message
Unsupported media data type: . Expected byte[] or String.
What it means
AnthropicChatModel's media-data extraction accepts only byte[] (Base64-encoded) and String (passed through as-is) as the data payload of a Media. Any other object type (InputStream, Resource, ByteBuffer, byte wrapper, etc.) reaches the final throw. The library cannot know how to serialize arbitrary types into an Anthropic block, so it fails fast with IllegalArgumentException.
Source
Thrown at models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/AnthropicChatModel.java:1405
private boolean isPdfMedia(MimeType mimeType) {
return "application".equals(mimeType.getType()) && "pdf".equals(mimeType.getSubtype());
}
/**
* Extracts media data as a string. Converts byte[] to base64, passes through URL
* strings.
* @param mediaData the media data (byte[] or String)
* @return base64-encoded string or URL string
* @throws IllegalArgumentException if data type is unsupported
*/
private String fromMediaData(Object mediaData) {
if (mediaData instanceof byte[] bytes) {
return Base64.getEncoder().encodeToString(bytes);
}
else if (mediaData instanceof String text) {
return text;
}
throw new IllegalArgumentException("Unsupported media data type: " + mediaData.getClass().getSimpleName()
+ ". Expected byte[] or String.");
}
/**
* Creates an {@link ImageBlockParam} from the given MIME type and data.
* @param mimeType the image MIME type (image/png, image/jpeg, etc.)
* @param data base64-encoded image data or HTTPS URL
* @return the ImageBlockParam wrapped in ContentBlockParam
*/
private ContentBlockParam createImageBlockParam(MimeType mimeType, String data) {
ImageBlockParam.Source source;
if (data.startsWith("https://")) {
source = ImageBlockParam.Source.ofUrl(UrlImageSource.builder().url(data).build());
}
else {
source = ImageBlockParam.Source
.ofBase64(Base64ImageSource.builder().data(data).mediaType(toSdkImageMediaType(mimeType)).build());
}View on GitHub (pinned to 98a7beda4f)
Solutions
- Convert the payload to byte[] before creating the Media (e.g. resource.getContentAsByteArray() or stream.readAllBytes()).
- For text media, pass the content as a String instead.
- Fix the generic MIME-type/empty-message case by ensuring mediaData is non-null so getClass().getSimpleName() is meaningful; null data indicates an earlier construction bug.
- Centralize a helper that normalizes Resource/InputStream inputs to byte[] for all Media construction in your codebase.
Example fix
// before
var media = new Media(MimeType.valueOf("image/png"), resource);
// after
var media = new Media(MimeType.valueOf("image/png"), resource.getContentAsByteArray()); Defensive patterns
Strategy: type-guard
Type guard
static boolean isSupportedMediaData(Object data) {
return data instanceof byte[] || data instanceof String;
}
// guard before building Media:
// if (!isSupportedMediaData(payload)) payload = toBytes(payload); Try / catch
try {
return client.call(prompt);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("Unsupported media data type")) {
throw new IllegalStateException("Convert media payload to byte[] or String before sending to Anthropic", e);
}
throw e;
} Prevention
- Always pass byte[] (or String for text) as Media data in Anthropic-bound prompts.
- Use resource.getContentAsByteArray() for Resource inputs instead of the Resource itself.
- Centralize Media creation in one helper so payload typing is enforced once.
When it happens
Trigger: Constructing Media with a payload that is not byte[] or String, e.g. new Media(mimeType, inputStream), new Media(mimeType, resource), a ByteBuffer, or a Media created by another integration (e.g. OpenAI module) that allows Resource payloads, then sending it through AnthropicChatModel.
Common situations: Reusing prompt-building code written for another Spring AI model (OpenAI accepts Resource); loading file content with Files.newInputStream and passing the stream directly; wrapping bytes in a custom DTO instead of raw byte[].
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Unsupported media type: . Supported types are: images (image
- Unsupported image type: . Supported types: image/png, image/
- httpClientBuilderCustomizers cannot be combined with a pre-b
- httpClientBuilderCustomizers cannot be combined with a pre-b
- Anthropic Citations API requires all documents to have consi
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/8516fc860ae5af0b.
Report an issue: GitHub.