spring-projects/spring-ai · warning

CassandraChatMemoryRepository does not support tool call mes

Error message

CassandraChatMemoryRepository does not support tool call messages. Some messages were filtered out for conversation: + conversationId

What it means

CassandraChatMemoryRepository.saveAll() filters out ToolResponseMessage and AssistantMessage instances that carry tool calls before persisting, because the Cassandra schema cannot store them. When any messages were dropped, it logs this warning naming the conversationId. Tool-call context is silently not persisted to Cassandra, so restored conversations lose tool history.

Source

Thrown at memory-repositories/spring-ai-model-chat-memory-repository-cassandra/src/main/java/org/springframework/ai/chat/memory/repository/cassandra/CassandraChatMemoryRepository.java:141

					messages.add(msg);
				}
			}
		}
		return messages;
	}

	@Override
	public void saveAll(String conversationId, List<Message> messages) {
		Assert.hasText(conversationId, "conversationId cannot be null or empty");
		Assert.notNull(messages, "messages cannot be null");
		Assert.noNullElements(messages, "messages cannot contain null elements");

		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(
					"CassandraChatMemoryRepository does not support tool call messages. Some messages were filtered out for conversation: "
							+ conversationId);
		}

		Instant instant = Instant.now();
		List<Object> primaryKeys = this.conf.primaryKeyTranslator.apply(conversationId);
		BoundStatementBuilder builder = this.addStmt.boundStatementBuilder();

		for (int k = 0; k < primaryKeys.size(); ++k) {
			CassandraChatMemoryRepositoryConfig.SchemaColumn keyColumn = this.conf.getPrimaryKeyColumn(k);
			builder = builder.set(keyColumn.name(), primaryKeys.get(k), keyColumn.javaType());
		}

		List<UdtValue> msgs = new ArrayList<>();
		for (Message msg : persistableMessages) {

			Preconditions.checkArgument(
					!msg.getMetadata().containsKey(CONVERSATION_TS)

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Strip tool-call messages yourself before saving so you control what is lost (filter ToolResponseMessage and AssistantMessage with tool calls)
  2. Switch to a repository that supports tool-call persistence (e.g. JDBC/JDBC-compatible stores or the in-memory repository) if tool history matters
  3. Persist tool-call context out-of-band (your own table keyed by conversationId) and reattach it when reloading the conversation
  4. Suppress the noise by filtering before the repository call so sizes match and the warning never fires

Example fix

// before
chatMemory.add(conversationId, assistantMessageWithToolCalls);

// after: persist only plain text messages
if (!(msg instanceof ToolResponseMessage)
        && !(msg instanceof AssistantMessage am && am.hasToolCalls())) {
    chatMemory.add(conversationId, msg);
}
Defensive patterns

Strategy: validation

Validate before calling

boolean persistable(Message m) {
    return !(m instanceof ToolResponseMessage)
        && !(m instanceof AssistantMessage am && am.hasToolCalls());
}
// call only: messages.stream().filter(this::persistable)... for Cassandra-backed memory

Type guard

static boolean isToolCallMessage(Message m) {
    return m instanceof ToolResponseMessage
        || (m instanceof AssistantMessage am && am.hasToolCalls());
}

Prevention

When it happens

Trigger: Calling saveAll (directly or via addAndGet) with a message list that contains a ToolResponseMessage or an AssistantMessage with hasToolCalls() == true for a given conversationId.

Common situations: Using tool-calling chat models with ChatMemory backed by Cassandra; agents that record tool executions in memory; replaying or migrating conversations that include tool-call history into Cassandra.

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


AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11). Data as JSON: /api/errors/12ee1ebe45263c3d. Report an issue: GitHub.