spring-projects/spring-ai · error · IllegalArgumentException

Unsupported media data type:

Error message

Unsupported media data type: 

What it means

fromMediaData(Object) maps user media to Mistral's ImageUrlChunk and supports byte[] (base64-encoded) and String (URL or base64 text); any other runtime type is rejected with IllegalArgumentException listing the class's simple name. Called via mapToImageUrlChunk when building multimodal user content.

Source

Thrown at models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/MistralAiChatModel.java:511

	private Stream<ChatCompletionMessage.ImageUrlChunk> mapToImageUrlChunks(UserMessage userMessage) {
		return userMessage.getMedia().stream().map(this::mapToImageUrlChunk);
	}

	private ChatCompletionMessage.ImageUrlChunk mapToImageUrlChunk(Media media) {
		return new ChatCompletionMessage.ImageUrlChunk(this.fromMediaData(media.getMimeType(), media.getData()));
	}

	private ChatCompletionMessage.ImageUrlChunk.ImageUrl fromMediaData(MimeType mimeType, Object mediaData) {
		if (mediaData instanceof byte[] bytes) {
			// Assume the bytes are an image.
			return ChatCompletionMessage.ImageUrlChunk.ImageUrl.fromImageData(mimeType, bytes);
		}
		else if (mediaData instanceof String text) {
			// Assume the text is a URL or a base64 encoded image prefixed by the user.
			return new ChatCompletionMessage.ImageUrlChunk.ImageUrl(text, null);
		}
		else {
			throw new IllegalArgumentException("Unsupported media data type: " + mediaData.getClass().getSimpleName());
		}
	}

	private List<MistralAiApi.FunctionTool> getFunctionTools(List<ToolDefinition> toolDefinitions) {
		return toolDefinitions.stream().map(toolDefinition -> {
			var function = new MistralAiApi.FunctionTool.Function(toolDefinition.description(), toolDefinition.name(),
					toolDefinition.inputSchema());
			return new MistralAiApi.FunctionTool(function);
		}).toList();
	}

	/**
	 * @since 2.0.0
	 */
	@Override
	public MistralAiChatOptions getOptions() {
		return this.options;
	}

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Pass the media as byte[] (raw image bytes) or String (public URL / base64)
  2. Convert URL/Resource/InputStream inputs: read bytes or call url.toString() before building Media
  3. Use Media.builder().url(...) handling or pre-fetch remote media into bytes

Example fix

// before
Media media = Media.builder().mimeType(MimeTypeUtils.IMAGE_PNG).data(resource).build();
// after
byte[] bytes = resource.getContentAsByteArray();
Media media = Media.builder().mimeType(MimeTypeUtils.IMAGE_PNG).data(bytes).build();
Defensive patterns

Strategy: type-guard

Validate before calling

Object data = media.getData();
if (!(data instanceof byte[] || data instanceof String)) {
    throw new IllegalArgumentException("media data must be byte[] or String url/base64, got " + data.getClass());
}

Type guard

boolean isSupportedMediaData(Object data) {
    return data instanceof byte[] || data instanceof String;
}

Try / catch

try {
    model.call(new Prompt(userMessage));
} catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("Unsupported media data type")) {
        logger.error("convert media to byte[]/String: {}", e.getMessage());
    } else throw e;
}

Prevention

When it happens

Trigger: Including Media with data of a type other than byte[] or String (e.g., URL, URI, Resource, InputStream, BufferedImage) in a UserMessage passed to MistralAiChatModel.

Common situations: Building multimodal prompts using Media.builder().data(URL) or a Resource loaded from classpath instead of pre-converting to a URL string or raw bytes.

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


AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11). Data as JSON: /api/errors/3bf823f69a275563. Report an issue: GitHub.