{"record":{"id":"8d379edbe4704875","repo":"spring-projects/spring-ai","slug":"unknown-message-type-s","errorCode":null,"errorMessage":"unknown message type %s","messagePattern":"unknown message type (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"memory-repositories/spring-ai-model-chat-memory-repository-cassandra/src/main/java/org/springframework/ai/chat/memory/repository/cassandra/CassandraChatMemoryRepository.java","lineNumber":240,"sourceCode":"\t\t\tstmt = stmt.whereColumn(columnName).isEqualTo(QueryBuilder.bindMarker(columnName));\n\t\t}\n\t\tstmt = stmt.limit(QueryBuilder.bindMarker(\"legacy_limit\"));\n\t\treturn this.conf.session.prepare(stmt.build());\n\t}\n\n\tprivate @Nullable Message getMessage(UdtValue udt) {\n\t\tString content = Objects.requireNonNullElse(udt.getString(this.conf.messageUdtContentColumn), \"\");\n\t\tMap<String, Object> props = Map.of(CONVERSATION_TS, udt.getInstant(this.conf.messageUdtTimestampColumn));\n\t\tString type = udt.getString(this.conf.messageUdtTypeColumn);\n\t\tAssert.state(type != null, \"message type shouldn't be null\");\n\t\treturn switch (MessageType.valueOf(type)) {\n\t\t\tcase ASSISTANT -> AssistantMessage.builder().content(content).properties(props).build();\n\t\t\tcase USER -> UserMessage.builder().text(content).metadata(props).build();\n\t\t\tcase SYSTEM -> SystemMessage.builder().text(content).metadata(props).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 -> throw new IllegalStateException(String.format(\"unknown message type %s\", type));\n\t\t};\n\t}\n\n}\n","sourceCodeStart":222,"sourceCodeEnd":245,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/memory-repositories/spring-ai-model-chat-memory-repository-cassandra/src/main/java/org/springframework/ai/chat/memory/repository/cassandra/CassandraChatMemoryRepository.java#L222-L245","documentation":"CassandraChatMemoryRepository.getMessage() maps stored message-type rows to Spring AI Message objects. Only SYSTEM, USER and ASSISTANT rows are supported; TOOL rows are intentionally filtered out by the caller, and any other (unknown) type hits the default branch, which throws IllegalStateException. This protects against corrupted or forward-incompatible rows written by a newer schema/version.","triggerScenarios":"Reading a conversation whose stored MESSAGE_TYPE column contains a value outside SYSTEM/USER/ASSISTANT/TOOL — e.g. a row written by a different or newer library version, or a manually inserted row with a typo'd type.","commonSituations":"Schema drift between library versions, manual CQL inserts into the messages table, or rows written by another tool sharing the same table/keyspace.","solutions":["Inspect the offending row with a CQL SELECT and fix or delete the row with the unexpected MESSAGE_TYPE","Align the library version that reads the table with the version that wrote it","Extend the switch to handle the new type if you control the code, or pre-filter unknown types in your query","Delete corrupted rows and re-save the conversation history"],"exampleFix":"// before\nRow badRow = rows with type 'FUNCTION';\nrepository.findByConversationId(\"conv1\"); // throws IllegalStateException\n// after\ncql> DELETE FROM ai_chat_memory WHERE conversation_id = 'conv1' AND message_type = 'FUNCTION';","handlingStrategy":"validation","validationCode":"List<Message> msgs = repo.findByConversationId(id);\nif (msgs == null || msgs.stream().anyMatch(m -> m.getMessageType() == null)) { /* handle bad data */ }","typeGuard":"boolean isKnownType(String t) { return t != null && List.of(\"USER\",\"ASSISTANT\",\"SYSTEM\",\"TOOL\").contains(t); }","tryCatchPattern":"try { messages = repo.findByConversationId(id); }\ncatch (IllegalStateException e) { messages = List.of(); logger.warn(\"Skipping conversation with unknown message type\", e); }","preventionTips":["Never hand-insert rows into the chat memory table","Keep reader and writer library versions in sync","Pre-filter by message type in your own queries"],"tags":["cassandra","chat-memory","state-exception","message-type"],"backgroundTag":"unsupported-enum-value","analyzedSha":"98a7beda4f29d80a71c5837eb4053b03a93a46f7","analyzedAt":"2026-09-11T14:15:49.441Z","contentChangedAt":"2026-09-11T14:15:49.441Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}