spring-projects/spring-ai · error · IllegalStateException

Unknown message type:

Error message

Unknown message type: 

What it means

MistralAiChatModel.createChatCompletionMessages(Message) switches on the Spring AI MessageType (USER, SYSTEM, ASSISTANT, TOOL) and throws IllegalStateException on any other value via the switch's default branch. In practice this only fires for custom/unknown message types.

Source

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

	private @Nullable List<MistralAiApi.FunctionTool> calculateToolsRequestParameter(MistralAiChatOptions options,
			ChatCompletionRequest request) {
		var tools = ModelOptionsUtils.mergeOption(options.getTools(), request.tools());
		var toolDefinitions = this.toolCallingManager.resolveToolDefinitions(options);

		if (!CollectionUtils.isEmpty(toolDefinitions)) {
			tools = this.getFunctionTools(toolDefinitions);
		}

		return tools;
	}

	private Stream<ChatCompletionMessage> createChatCompletionMessages(Message message) {
		return switch (message.getMessageType()) {
			case USER -> Stream.of(createUserChatCompletionMessage(message));
			case SYSTEM -> Stream.of(createSystemChatCompletionMessage(message));
			case ASSISTANT -> Stream.of(createAssistantChatCompletionMessage(message));
			case TOOL -> createToolChatCompletionMessages(message);
			default -> throw new IllegalStateException("Unknown message type: " + message.getMessageType());
		};
	}

	private Stream<ChatCompletionMessage> createToolChatCompletionMessages(Message message) {
		if (message instanceof ToolResponseMessage toolResponseMessage) {
			// @formatter:off
			return toolResponseMessage.getResponses()
				.stream()
				.map(this::createToolChatCompletionMessage);
			// @formatter:on
		}
		else {
			throw new IllegalArgumentException("Unsupported tool message class: " + message.getClass().getName());
		}
	}

	private ChatCompletionMessage createToolChatCompletionMessage(ToolResponseMessage.ToolResponse toolResponse) {
		return new ChatCompletionMessage(toolResponse.responseData(), ChatCompletionMessage.Role.TOOL,

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Use standard Spring AI message classes (UserMessage, SystemMessage, AssistantMessage, ToolResponseMessage)
  2. Check for library upgrades that introduced new MessageType values and update/upgrade accordingly
  3. Filter out or map unsupported messages before calling the model

Example fix

// before
messages.add(new CustomMessage("hi"));
// after
messages.add(new UserMessage("hi"));
Defensive patterns

Strategy: type-guard

Validate before calling

Set<MessageType> supported = Set.of(MessageType.USER, MessageType.SYSTEM, MessageType.ASSISTANT, MessageType.TOOL);
if (!supported.contains(msg.getMessageType())) throw new IllegalArgumentException("unsupported type: " + msg.getMessageType());

Type guard

boolean isSupportedMessageType(Message m) {
    return switch (m.getMessageType()) {
        case USER, SYSTEM, ASSISTANT, TOOL -> true;
        default -> false;
    };
}

Try / catch

try {
    model.call(new Prompt(messages));
} catch (IllegalStateException e) {
    if (e.getMessage().startsWith("Unknown message type")) {
        logger.error("filter unsupported message: {}", e.getMessage());
    } else throw e;
}

Prevention

When it happens

Trigger: Passing a Message whose getMessageType() is not one of USER, SYSTEM, ASSISTANT, TOOL (e.g., a custom Message implementation) to the chat model's internal call building.

Common situations: Custom Message implementations with a novel MessageType used with MistralAiChatModel, or library version changes adding a MessageType not yet handled.

Related errors


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