{"record":{"id":"ebc4bd3c72024f59","repo":"spring-projects/spring-ai","slug":"unsupported-message-type-conversation-message","errorCode":null,"errorMessage":"Unsupported message type: + conversation.message().type()","messagePattern":"Unsupported message type: \\+ conversation\\.message\\(\\)\\.type\\(\\)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"memory-repositories/spring-ai-model-chat-memory-repository-mongodb/src/main/java/org/springframework/ai/chat/memory/repository/mongo/MongoChatMemoryRepository.java","lineNumber":105,"sourceCode":"\n\t@Override\n\tpublic void deleteByConversationId(String conversationId) {\n\t\tthis.mongoTemplate.remove(Query.query(Criteria.where(\"conversationId\").is(conversationId)), Conversation.class);\n\t}\n\n\tpublic static @Nullable Message mapMessage(Conversation conversation) {\n\t\tfinal String content = Objects.requireNonNullElse(conversation.message().content(), \"\");\n\t\treturn switch (conversation.message().type()) {\n\t\t\tcase \"USER\" -> UserMessage.builder().text(content).metadata(conversation.message().metadata()).build();\n\t\t\tcase \"ASSISTANT\" ->\n\t\t\t\tAssistantMessage.builder().content(content).properties(conversation.message().metadata()).build();\n\t\t\tcase \"SYSTEM\" -> SystemMessage.builder().text(content).metadata(conversation.message().metadata()).build();\n\t\t\t// this implementation doesn't support tool calls message persistence, so\n\t\t\t// TOOL rows are filtered out by the caller\n\t\t\tcase \"TOOL\" -> null;\n\t\t\tdefault -> {\n\t\t\t\tif (logger.isWarnEnabled()) {\n\t\t\t\t\tlogger.warn(\"Unsupported message type: \" + conversation.message().type());\n\t\t\t\t}\n\t\t\t\tthrow new IllegalStateException(\"Unsupported message type: \" + conversation.message().type());\n\t\t\t}\n\t\t};\n\t}\n\n\tpublic static Builder builder() {\n\t\treturn new Builder();\n\t}\n\n\tpublic final static class Builder {\n\n\t\tprivate @Nullable MongoTemplate mongoTemplate;\n\n\t\tprivate Builder() {\n\t\t}\n\n\t\tpublic Builder mongoTemplate(MongoTemplate mongoTemplate) {","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/memory-repositories/spring-ai-model-chat-memory-repository-mongodb/src/main/java/org/springframework/ai/chat/memory/repository/mongo/MongoChatMemoryRepository.java#L87-L123","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Inspect the offending document in the conversation's Mongo collection and fix or remove the record with the unknown type","Check for a spring-ai version mismatch between the writer and reader of the documents; align versions and re-migrate data","Sanitize data after migrations: normalize type values to the enum the repository expects","If you need custom message types, wrap/translate them to supported types before persistence, or fork mapMessage in a custom repository implementation"],"exampleFix":"// before: legacy docs carry type \"FUNCTION_CALL\" the repo can't read\nList<Message> messages = repository.findByConversationId(id);\n\n// after: migrate or sanitize at read time\nconversation.type() -> switch normalize: \"FUNCTION_CALL\" -> \"ASSISTANT\" (with tool calls stripped)\n// or one-off cleanup:\n// db.getCollection('ai_chat_memory').updateMany({type:'FUNCTION_CALL'}, {$set:{type:'ASSISTANT'}})","handlingStrategy":"try-catch","validationCode":"// validate stored documents before loading\nif (!Set.of(\"USER\",\"ASSISTANT\",\"SYSTEM\",\"TOOL\").contains(conversation.message().type())) {\n    logger.warn(\"Skipping document with unknown type {}\", conversation.message().type());\n}","typeGuard":"boolean isKnownType(String type) {\n    return Set.of(\"USER\", \"ASSISTANT\", \"SYSTEM\", \"TOOL\").contains(type);\n}","tryCatchPattern":"try {\n    List<Message> messages = repository.findByConversationId(conversationId);\n} catch (IllegalStateException e) {\n    logger.error(\"Conversation {} contains unknown message type; inspect the Mongo collection\", conversationId, e);\n    // fall back to a fresh conversation or quarantine the bad document\n}","preventionTips":["Keep writer and reader spring-ai versions aligned","Migrate data with type normalization when upgrading","Restrict the shared Mongo collection to applications using the same schema","Validate documents after any manual data import or migration"],"tags":["mongodb","chat-memory","illegal-state","data-migration"],"backgroundTag":"unexpected-api-response-shape","analyzedSha":"98a7beda4f29d80a71c5837eb4053b03a93a46f7","analyzedAt":"2026-09-11T14:15:49.441Z","contentChangedAt":"2026-09-11T14:15:49.441Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}