spring-projects/spring-ai · error · IllegalArgumentException
%s messages are not supported
Error message
%s messages are not supported
What it means
Neo4jChatMemoryRepository.findByConversationId() builds Message objects from query records. TOOL records are built via buildToolMessage but are not supported as returned messages in this path; when the resulting message is null the repository throws IllegalArgumentException naming the unsupported type. Essentially TOOL-typed rows cannot be materialized here.
Source
Thrown at memory-repositories/spring-ai-model-chat-memory-repository-neo4j/src/main/java/org/springframework/ai/chat/memory/repository/neo4j/Neo4jChatMemoryRepository.java:116
message = buildUserMessage(record, messageMap, mediaList);
}
else if (msgType.equals(MessageType.ASSISTANT.getValue())) {
message = buildAssistantMessage(record, messageMap, mediaList);
}
else if (msgType.equals(MessageType.SYSTEM.getValue())) {
SystemMessage.Builder systemMessageBuilder = SystemMessage.builder()
.text(MessageAttributes.TEXT_CONTENT.stringFrom(messageMap));
if (!record.get("metadata").isNull()) {
Map<String, Object> retrievedMetadata = record.get("metadata").asMap();
systemMessageBuilder.metadata(retrievedMetadata);
}
message = systemMessageBuilder.build();
}
else if (msgType.equals(MessageType.TOOL.getValue())) {
message = buildToolMessage(record);
}
if (message == null) {
throw new IllegalArgumentException("%s messages are not supported"
.formatted(record.get(MessageAttributes.MESSAGE_TYPE.getValue()).asString()));
}
message.getMetadata().put("messageType", message.getMessageType());
return message;
}, Collectors.toList()));
}
@Override
public void saveAll(String conversationId, List<Message> messages) {
// First delete existing messages for this conversation
deleteByConversationId(conversationId);
// Then add the new messages
try (Session s = this.config.getDriver().session()) {
s.executeWriteWithoutResult(tx -> {
for (Message m : messages) {
addMessageToTransaction(tx, conversationId, m);View on GitHub (pinned to 98a7beda4f)
Solutions
- Remove or re-type the TOOL message nodes for that conversation
- Keep TOOL interactions out of the persisted history (filter before saving)
- Upgrade/align library versions if TOOL support changed between releases
Example fix
// before
MATCH (m:Message {conversationId:'c1', messageType:'TOOL'}) // read throws IAE
// after
MATCH (m:Message {conversationId:'c1'}) WHERE m.messageType <> 'TOOL' RETURN m Defensive patterns
Strategy: validation
Validate before calling
// before reading, ensure no TOOL-typed nodes exist for the conversation
// MATCH (m:Message {conversationId:$id, messageType:'TOOL'}) RETURN count(m) == 0 Try / catch
try { messages = repo.findByConversationId(id); }
catch (IllegalArgumentException e) { messages = List.of(); logger.warn("Conversation contains unsupported message nodes", e); } Prevention
- Filter TOOL interactions out before saving history
- Don't write message nodes with custom code into the repository's graph
- Align library versions across services using the same Neo4j database
When it happens
Trigger: A conversation in Neo4j contains a node whose messageType is TOOL (or otherwise yields a null message), and findByConversationId is called on that conversation.
Common situations: Tool-call results were persisted by custom code or an older/other tool into the message nodes; mixed-version data; manual graph inserts.
Related errors
- unknown message type %s
- Unsupported message type:
- Invalid Neo4j node label: ''. Labels must start with a lette
- Unsupported message type:
- Unsupported message type:
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/d611d152b9eb3e06.
Report an issue: GitHub.