spring-projects/spring-ai · warning
MongoChatMemoryRepository does not support tool call message
Error message
MongoChatMemoryRepository does not support tool call messages. Some messages were filtered out for conversation: + conversationId
What it means
MongoChatMemoryRepository.saveAll() filters out ToolResponseMessage and tool-calling AssistantMessage objects because tool-call messages are not persisted in MongoDB, logging this warning when any were dropped. The conversation is then rewritten (delete + insert) without the tool-call history.
Source
Thrown at memory-repositories/spring-ai-model-chat-memory-repository-mongodb/src/main/java/org/springframework/ai/chat/memory/repository/mongo/MongoChatMemoryRepository.java:75
return this.mongoTemplate.query(Conversation.class).distinct("conversationId").as(String.class).all();
}
@Override
public List<Message> findByConversationId(String conversationId) {
var messages = this.mongoTemplate.query(Conversation.class)
.matching(Query.query(Criteria.where("conversationId").is(conversationId))
.with(Sort.by("timestamp").ascending()));
return messages.stream().map(MongoChatMemoryRepository::mapMessage).filter(Objects::nonNull).toList();
}
@Override
public void saveAll(String conversationId, List<Message> messages) {
List<Message> persistableMessages = messages.stream()
.filter(m -> !(m instanceof ToolResponseMessage)
&& !(m instanceof AssistantMessage am && am.hasToolCalls()))
.toList();
if (logger.isWarnEnabled() && persistableMessages.size() < messages.size()) {
logger.warn(
"MongoChatMemoryRepository does not support tool call messages. Some messages were filtered out for conversation: "
+ conversationId);
}
deleteByConversationId(conversationId);
var conversations = persistableMessages.stream()
.map(message -> new Conversation(conversationId,
new Conversation.Message(message.getText(), message.getMessageType().name(), message.getMetadata()),
Instant.now()))
.toList();
this.mongoTemplate.insert(conversations, Conversation.class);
}
@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) {View on GitHub (pinned to 98a7beda4f)
Solutions
- Filter tool-call messages yourself before calling the repository so the behavior is explicit and warning-free
- If tool history is essential, use a memory store that persists tool messages (in-memory, or a custom repository)
- Persist tool-call exchanges to a separate Mongo collection yourself and rehydrate them when building the prompt
- Upgrade spring-ai and check release notes — tool-call persistence support has been added progressively across repositories
Example fix
// before
chatMemory.add(conversationId, toolResponseMessage); // dropped, warning logged
// after
if (!(msg instanceof ToolResponseMessage)
&& !(msg instanceof AssistantMessage am && am.hasToolCalls())) {
chatMemory.add(conversationId, msg);
} else {
toolCallArchive.insert(conversationId, msg); // custom persistence
} Defensive patterns
Strategy: validation
Validate before calling
boolean persistable(Message m) {
return !(m instanceof ToolResponseMessage)
&& !(m instanceof AssistantMessage am && am.hasToolCalls());
} Type guard
static boolean isToolCallMessage(Message m) {
return m instanceof ToolResponseMessage
|| (m instanceof AssistantMessage am && am.hasToolCalls());
} Prevention
- Filter tool messages before calling Mongo-backed chat memory
- Archive tool calls to a dedicated Mongo collection if history is needed
- Add a round-trip test: save messages with tools, reload, assert expectations
- Check spring-ai release notes for added tool-call persistence before working around it
When it happens
Trigger: Calling saveAll (directly or via addAndGet) with a message list that contains ToolResponseMessage or AssistantMessage.hasToolCalls() for the given conversationId.
Common situations: Agents using function/tool calling with MongoDB-backed ChatMemory; moving from in-memory memory (tool messages retained) to Mongo and losing tool context; conversations appearing shorter or lacking tool results after reload.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- CassandraChatMemoryRepository does not support tool call mes
- JdbcChatMemoryRepository does not support tool call messages
- Unsupported message type:
- Dropping existing TTL index, because TTL is different
- Unsupported message type: + conversation.message().type()
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/8e6383d276284d21.
Report an issue: GitHub.