spring-projects / spring-projects/spring-ai
RedisChatMemoryRepository auto-config backs off when any ChatMemory bean exists (ChatMemory.class in ConditionalOnMissingBean)
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 9.5k
- Forks
- 2.9k
- Avg merge
- 1d 7h
- Merged PRs (30d)
- 6
Description
Bug description
RedisChatMemoryRepositoryAutoConfiguration refuses to register RedisChatMemoryRepository when any ChatMemory bean is already present:
@Bean
@ConditionalOnMissingBean({ RedisChatMemoryRepository.class, ChatMemory.class, ChatMemoryRepository.class })
public RedisChatMemoryRepository redisChatMemoryRepository(...) { ... }
That condition is too broad for a repository auto-configuration.
Spring AI separates responsibilities clearly:
ChatMemoryRepository– persistenceChatMemory– retention strategy (e.g.MessageWindowChatMemorywithmaxMessages)
The docs encourage adding the Redis starter for auto-configured RedisChatMemoryRepository, and then customizing ChatMemory on top of that repository. Including ChatMemory.class in @ConditionalOnMissingBean breaks that pattern: defining a custom ChatMemory suppresses Redis repository auto-config entirely.
Even without a custom bean, ChatMemoryAutoConfiguration always provides a default ChatMemory, so any scenario where that bean is visible before Redis auto-config evaluates will also suppress RedisChatMemoryRepository.
Comparison with sibling store auto-configs
JdbcChatMemoryRepositoryAutoConfiguration and CassandraChatMemoryRepositoryAutoConfiguration only use @ConditionalOnMissingBean on the repository type itself — they do not back off because a ChatMemory exists. Redis should follow the same pattern.
Relation to #5623 / #5644 (please do not close as duplicate without checking main)
This is related to https://github.com/spring-projects/spring-ai/issues/5623, but it is not fully resolved on current main.
PR https://github.com/spring-projects/spring-ai/pull/5644 explicitly fixed the same root cause for the older RedisChatMemoryAutoConfiguration by:
- ordering Redis auto-config before
ChatMemoryAutoConfiguration - narrowing the missing-bean condition to
ChatMemoryRepositoryonly (removingChatMemory.class)
Relevant change from that PR:
- @ConditionalOnMissingBean({ RedisChatMemoryRepository.class, ChatMemory.class, ChatMemoryRepository.class })
+ @ConditionalOnMissingBean(ChatMemoryRepository.class)
However, on current main, the successor module RedisChatMemoryRepositoryAutoConfiguration still has:
@ConditionalOnMissingBean({ RedisChatMemoryRepository.class, ChatMemory.class, ChatMemoryRepository.class })
So the before = ChatMemoryAutoConfiguration.class ordering helps the default InMemory vs Redis race, but ChatMemory.class being part of the condition remains a regression / incomplete fix relative to what #5644 proposed.
Environment
- Spring AI
main(verified against currentRedisChatMemoryRepositoryAutoConfiguration) spring-ai-starter-model-chat-memory-repository-redis
Steps to reproduce
- Add
spring-ai-starter-model-chat-memory-repository-redis. - Declare a custom
ChatMemorythat depends on the auto-configured Redis repository, e.g.:
@Bean
public ChatMemory chatMemory(RedisChatMemoryRepository redisChatMemoryRepository) {
return MessageWindowChatMemory.builder()
.chatMemoryRepository(redisChatMemoryRepository)
.maxMessages(20)
.build();
}
- Start the application.
Expected behavior
RedisChatMemoryRepositoryis auto-configured when noChatMemoryRepository(or Redis-specific repository) bean exists.- A user-defined
ChatMemorymust not prevent Redis repository auto-configuration. - Align Redis with JDBC/Cassandra: repository auto-config should not condition on
ChatMemory.class.
Actual behavior
Because a ChatMemory bean is present, RedisChatMemoryRepository is not registered. The custom ChatMemory bean then fails to obtain RedisChatMemoryRepository, or the app falls back to in-memory storage depending on ordering / other beans.
Suggested fix
Narrow the condition back to repository types only, as in #5644, for example:
@ConditionalOnMissingBean(ChatMemoryRepository.class)
// or at most:
@ConditionalOnMissingBean({ RedisChatMemoryRepository.class, ChatMemoryRepository.class })
and add a regression test where a user-provided ChatMemory bean still receives an auto-configured RedisChatMemoryRepository.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with auto-configurations/models/chat/memory/repository/spring-ai-autoconfigure-model-chat-memory-repository-redis/src/main/java/org/springframework/ai/model/chat/memory/repository/redis/autoconfigure/RedisChatMemoryRepositoryAutoConfiguration.java and compare the JDBC and Cassandra conditions. Add a regression test for a user-provided ChatMemory receiving the Redis repository, then run the relevant Redis repository auto-configuration tests; done means ChatMemory no longer suppresses repository creation.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, spring-boot
- Domain
- backend, testing
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 82/100