spring-projects/spring-ai · error · java.lang.IllegalArgumentException

Unsupported media data type:

Error message

Unsupported media data type: 

What it means

In the image model's mediaToParts(), Media data must be a byte[] (sent via Part.fromBytes) or a URI/String URL (sent via Part.fromUri). Any other data type cannot be converted to a Gemini Part, so an IllegalArgumentException naming the actual class is thrown.

Source

Thrown at models/spring-ai-google-genai-image/src/main/java/org/springframework/ai/google/genai/image/GoogleGenAiImageModel.java:371

			parts.addAll(mediaToParts(message.getMedia()));
		}

		return parts;
	}

	private static List<Part> mediaToParts(Collection<Media> media) {
		return media.stream().map(mediaData -> {
			final Object data = mediaData.getData();
			final String mimeType = mediaData.getMimeType().toString();

			if (data instanceof byte[]) {
				return Part.fromBytes((byte[]) data, mimeType);
			}
			if (data instanceof URI || data instanceof String) {
				return Part.fromUri(data.toString(), mimeType);
			}

			throw new IllegalArgumentException("Unsupported media data type: " + data.getClass());
		}).toList();
	}

	private static List<SafetySetting> buildSafetySettings(
			GoogleGenAiImageOptions.SafetyFilterLevel safetyFilterLevel) {
		final String threshold = safetyFilterLevel.name();
		final List<HarmCategory.Known> categories = List.of(HarmCategory.Known.HARM_CATEGORY_HARASSMENT,
				HarmCategory.Known.HARM_CATEGORY_HATE_SPEECH, HarmCategory.Known.HARM_CATEGORY_SEXUALLY_EXPLICIT,
				HarmCategory.Known.HARM_CATEGORY_DANGEROUS_CONTENT);

		final List<SafetySetting> safetySettings = new ArrayList<>();
		for (HarmCategory.Known category : categories) {
			safetySettings.add(SafetySetting.builder().category(category).threshold(threshold).build());
		}

		return safetySettings;
	}

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Convert the data to byte[] first (e.g. resource.getContentAsByteArray() or Files.readAllBytes(path)) and pass that as Media data.
  2. If the image is reachable by URL, pass a java.net.URI or its toString() so it is sent via Part.fromUri.
  3. Wrap the conversion in a helper that normalizes InputStream/File/Resource to byte[] before building the Media.

Example fix

// before
Media media = new Media(MimeTypeUtils.IMAGE_PNG, new ClassPathResource("cat.png"));

// after
byte[] bytes = new ClassPathResource("cat.png").getContentAsByteArray();
Media media = new Media(MimeTypeUtils.IMAGE_PNG, bytes);
Defensive patterns

Strategy: type-guard

Type guard

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

Prevention

When it happens

Trigger: Constructing a Media (e.g. new Media(MimeTypeUtils.IMAGE_PNG, someObject)) where data is an InputStream, File, Path, Resource, or BufferedImage instead of byte[] or URI/String, then passing it through an ImagePrompt message.

Common situations: Loading images via ClassPathResource/FileInputStream and passing the Resource or InputStream directly as Media data; using Path objects from java.nio; code migrated from another AI model API that accepted Resources.

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/ae64bd0a228c5c0b. Report an issue: GitHub.