{"record":{"id":"3b1c5246b956d00a","repo":"spring-projects/spring-ai","slug":"unknown-message-type","errorCode":null,"errorMessage":"Unknown message type: ","messagePattern":"Unknown message type: ","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"advisors/spring-ai-vector-store-advisor/src/main/java/org/springframework/ai/chat/client/advisor/vectorstore/VectorStoreChatMemoryAdvisor.java","lineNumber":235,"sourceCode":"\t\t\t.map(message -> {\n\t\t\t\tMap<String, Object> metadata = new HashMap<>(\n\t\t\t\t\t\tmessage.getMetadata() != null ? message.getMetadata() : new HashMap<>());\n\t\t\t\tmetadata.put(DOCUMENT_METADATA_CONVERSATION_ID, conversationId);\n\t\t\t\tmetadata.put(DOCUMENT_METADATA_MESSAGE_TYPE, message.getMessageType().name());\n\t\t\t\tif (message instanceof UserMessage userMessage) {\n\t\t\t\t\treturn Document.builder()\n\t\t\t\t\t\t.text(userMessage.getText())\n\t\t\t\t\t\t// userMessage.getMedia().get(0).getId()\n\t\t\t\t\t\t// TODO vector store for memory would not store this into the\n\t\t\t\t\t\t// vector store, could store an 'id' instead\n\t\t\t\t\t\t// .media(userMessage.getMedia())\n\t\t\t\t\t\t.metadata(metadata)\n\t\t\t\t\t\t.build();\n\t\t\t\t}\n\t\t\t\telse if (message instanceof AssistantMessage assistantMessage) {\n\t\t\t\t\treturn Document.builder().text(assistantMessage.getText()).metadata(metadata).build();\n\t\t\t\t}\n\t\t\t\tthrow new RuntimeException(\"Unknown message type: \" + message.getMessageType());\n\t\t\t})\n\t\t\t.toList();\n\t}\n\n\t/**\n\t * Builder for VectorStoreChatMemoryAdvisor.\n\t */\n\tpublic static final class Builder {\n\n\t\tprivate PromptTemplate systemPromptTemplate = DEFAULT_SYSTEM_PROMPT_TEMPLATE;\n\n\t\tprivate Integer defaultTopK = DEFAULT_TOP_K;\n\n\t\tprivate Scheduler scheduler = BaseAdvisor.DEFAULT_SCHEDULER;\n\n\t\tprivate int order = Advisor.DEFAULT_CHAT_MEMORY_PRECEDENCE_ORDER;\n\n\t\tprivate final VectorStore vectorStore;","sourceCodeStart":217,"sourceCodeEnd":253,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/advisors/spring-ai-vector-store-advisor/src/main/java/org/springframework/ai/chat/client/advisor/vectorstore/VectorStoreChatMemoryAdvisor.java#L217-L253","documentation":"VectorStoreChatMemoryAdvisor.toDocuments converts the conversation's messages into Documents for the vector store, mapping UserMessage, SystemMessage and AssistantMessage types. If a message of another MessageType appears in the list, it throws this RuntimeException because there is no mapping for it. This typically happens when tool/function-call or ToolResponseMessage instances end up in the memory history.","triggerScenarios":"Calling advisor.before/after on a conversation whose Message list contains a message that is not a UserMessage, SystemMessage or AssistantMessage (e.g. ToolResponseMessage from tool-calling results).","commonSituations":"Using ChatMemory that stores tool execution responses, then re-serving that memory to a conversation augmented with the vector-store memory advisor; mixing memory advisors that record full tool-call transcripts.","solutions":["Filter the memory to only user/assistant/system messages before it reaches the advisor.","Use a memory implementation or window that excludes ToolResponseMessage entries.","Upgrade spring-ai — newer versions may add handling for additional message types.","As a workaround, wrap the ChatMemory so add() skips tool-response messages."],"exampleFix":"// before\nchatMemory.add(conversationId, toolResponseMessage);\n\n// after\nif (message instanceof UserMessage || message instanceof AssistantMessage || message instanceof SystemMessage) {\n    chatMemory.add(conversationId, message);\n}","handlingStrategy":"type-guard","validationCode":"boolean memorySafe(List<Message> messages) { return messages.stream().allMatch(m -> m instanceof UserMessage || m instanceof AssistantMessage || m instanceof SystemMessage); }","typeGuard":"boolean isSupportedMessageType(Message m) {\n    return m instanceof UserMessage || m instanceof AssistantMessage || m instanceof SystemMessage;\n}","tryCatchPattern":"try {\n    return advisor.before(body, call);\n} catch (RuntimeException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"Unknown message type:\")) {\n        // purge tool-response messages from memory and retry\n    }\n    throw e;\n}","preventionTips":["Store only user/assistant/system messages in ChatMemory","Filter ToolResponseMessage out before handing history to the advisor","Keep spring-ai versions aligned across advisor modules","Unit-test memory round-trips with tool-calling conversations"],"tags":["vector-store","memory","chat-messages","unsupported-type"],"backgroundTag":"unsupported-operation","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"}