spring-projects/spring-ai · error

Unsupported message type: + conversation.message().type()

Error message

Unsupported message type: + conversation.message().type()

What it means

MongoChatMemoryRepository.mapMessage() switches on the stored message type string (USER, ASSISTANT, SYSTEM, TOOL) when loading a conversation. If it encounters a type it does not recognize, it logs this warning and throws IllegalStateException. This guards against documents written by other/older schema versions or corrupted data.

Source

Thrown at memory-repositories/spring-ai-model-chat-memory-repository-mongodb/src/main/java/org/springframework/ai/chat/memory/repository/mongo/MongoChatMemoryRepository.java:105

	@Override
	public void deleteByConversationId(String conversationId) {
		this.mongoTemplate.remove(Query.query(Criteria.where("conversationId").is(conversationId)), Conversation.class);
	}

	public static @Nullable Message mapMessage(Conversation conversation) {
		final String content = Objects.requireNonNullElse(conversation.message().content(), "");
		return switch (conversation.message().type()) {
			case "USER" -> UserMessage.builder().text(content).metadata(conversation.message().metadata()).build();
			case "ASSISTANT" ->
				AssistantMessage.builder().content(content).properties(conversation.message().metadata()).build();
			case "SYSTEM" -> SystemMessage.builder().text(content).metadata(conversation.message().metadata()).build();
			// this implementation doesn't support tool calls message persistence, so
			// TOOL rows are filtered out by the caller
			case "TOOL" -> null;
			default -> {
				if (logger.isWarnEnabled()) {
					logger.warn("Unsupported message type: " + conversation.message().type());
				}
				throw new IllegalStateException("Unsupported message type: " + conversation.message().type());
			}
		};
	}

	public static Builder builder() {
		return new Builder();
	}

	public final static class Builder {

		private @Nullable MongoTemplate mongoTemplate;

		private Builder() {
		}

		public Builder mongoTemplate(MongoTemplate mongoTemplate) {

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Inspect the offending document in the conversation's Mongo collection and fix or remove the record with the unknown type
  2. Check for a spring-ai version mismatch between the writer and reader of the documents; align versions and re-migrate data
  3. Sanitize data after migrations: normalize type values to the enum the repository expects
  4. If you need custom message types, wrap/translate them to supported types before persistence, or fork mapMessage in a custom repository implementation

Example fix

// before: legacy docs carry type "FUNCTION_CALL" the repo can't read
List<Message> messages = repository.findByConversationId(id);

// after: migrate or sanitize at read time
conversation.type() -> switch normalize: "FUNCTION_CALL" -> "ASSISTANT" (with tool calls stripped)
// or one-off cleanup:
// db.getCollection('ai_chat_memory').updateMany({type:'FUNCTION_CALL'}, {$set:{type:'ASSISTANT'}})
Defensive patterns

Strategy: try-catch

Validate before calling

// validate stored documents before loading
if (!Set.of("USER","ASSISTANT","SYSTEM","TOOL").contains(conversation.message().type())) {
    logger.warn("Skipping document with unknown type {}", conversation.message().type());
}

Type guard

boolean isKnownType(String type) {
    return Set.of("USER", "ASSISTANT", "SYSTEM", "TOOL").contains(type);
}

Try / catch

try {
    List<Message> messages = repository.findByConversationId(conversationId);
} catch (IllegalStateException e) {
    logger.error("Conversation {} contains unknown message type; inspect the Mongo collection", conversationId, e);
    // fall back to a fresh conversation or quarantine the bad document
}

Prevention

When it happens

Trigger: Reading a Conversation document whose message().type() is not one of USER/ASSISTANT/SYSTEM/TOOL — typically documents written by a different library version, manual edits, data migrations, or corrupted type fields.

Common situations: Upgrading/downgrading spring-ai versions where message type enums changed; a migration script writing new type values; hand-crafted test documents with bad types; another application sharing the same Mongo collection with its own message format.

Understand the failure class

Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.

Related errors


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