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

Gemini doesn't support message type:

Error message

Gemini doesn't support message type: 

What it means

GoogleGenAiChatModel.messageToGeminiParts() handles SystemMessage, UserMessage, AssistantMessage, and ToolResponseMessage. Gemini has no representation for any other Message class, so the else branch throws this IllegalArgumentException naming the actual message class.

Source

Thrown at models/spring-ai-google-genai/src/main/java/org/springframework/ai/google/genai/GoogleGenAiChatModel.java:322

				}
			}

			return parts;
		}
		else if (message instanceof ToolResponseMessage toolResponseMessage) {

			return toolResponseMessage.getResponses()
				.stream()
				.map(response -> Part.builder()
					.functionResponse(FunctionResponse.builder()
						.name(response.name())
						.response(parseJsonToMap(response.responseData()))
						.build())
					.build())
				.toList();
		}
		else {
			throw new IllegalArgumentException("Gemini doesn't support message type: " + message.getClass());
		}
	}

	private static List<Part> mediaToParts(Collection<Media> media) {
		List<Part> parts = new ArrayList<>();

		List<Part> mediaParts = media.stream().map(mediaData -> {
			Object data = mediaData.getData();
			String mimeType = mediaData.getMimeType().toString();

			if (data instanceof byte[]) {
				return Part.fromBytes((byte[]) data, mimeType);
			}
			else if (data instanceof URI || data instanceof String) {
				// Handle URI or String URLs
				String uri = data.toString();
				return Part.fromUri(uri, mimeType);
			}

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Convert unsupported messages to the supported types (SystemMessage/UserMessage/AssistantMessage/ToolResponseMessage) before building the Prompt.
  2. If it is a custom Message subclass, refactor it to extend one of the standard Spring AI message classes.
  3. Filter out unsupported message kinds from the prompt history with an explicit, logged decision instead of silently passing them.

Example fix

// before
List<Message> msgs = List.of(new MyMessage("hello")); // custom type
Prompt prompt = new Prompt(msgs);

// after
List<Message> msgs = List.of(new UserMessage("hello"));
Prompt prompt = new Prompt(msgs);
Defensive patterns

Strategy: type-guard

Type guard

static boolean isGeminiSupported(Message m) {
    return m instanceof SystemMessage || m instanceof UserMessage
        || m instanceof AssistantMessage || m instanceof ToolResponseMessage;
}

Prevention

When it happens

Trigger: Including a Message instance that is not one of the four supported types (e.g. a custom Message subclass or a legacy/deprecated message type) in the Prompt's messages list passed to call() or stream().

Common situations: Custom Message implementations from application code that worked with other model adapters but not the Gemini one; copied prompt-building code referencing an old message type; bridging another framework's message objects into a Spring AI Prompt without conversion.

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


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