spring-projects / spring-projects/spring-ai
ToolResponseMessage results in null content, causing SQLIntegrityConstraintViolationException in JdbcChatMemoryRepository
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 9.5k
- Forks
- 2.9k
- Avg merge
- 1d 10h
- Merged PRs (30d)
- 5
Description
Bug description
When a ChatResponse from the model includes a ToolCall (i.e., finishReason=TOOL_CALLS), the corresponding AssistantMessage has textContent = null.
When this message is added to the JdbcChatMemoryRepository, the implementation attempts to insert it into the database without null-checking the content field. This causes a SQL integrity error due to a NOT NULL constraint on the content column.
The ToolResponseMessage (or AssistantMessage with only toolCalls and no content) is not handled correctly in JdbcChatMemoryRepository. This leads to the following exception:
java.sql.SQLIntegrityConstraintViolationException: (conn=498) Column 'content' cannot be null
In contrast, the default in-memory implementation (MessageWindowChatMemory) tolerates null content and saving such messages with null textContent.
Environment
- spring-ai 1.0.0
- mariadb:10.11
Steps to reproduce
- Use a ChatModel that returns a response containing only toolCalls (e.g., OpenAI with function/tool calling).
- Capture that AssistantMessage and attempt to save it to JdbcChatMemoryRepository.
- Since textContent == null, the following SQL fails:
INSERT INTO SPRING_AI_CHAT_MEMORY (conversation_id, content, type, timestamp)
VALUES (?, NULL, 'ASSISTANT', ?)
.
Expected behavior
The repository should store the response with null value
Minimal Complete Reproducible example
Here is the code that caused the bug in my project.
fun call(conversationId: String, prompt: Prompt, toolCallingChatOption: ToolCallingChatOptions?): ChatResponse {
val systemMessage = prompt.systemMessage
chatMemory.add(conversationId, prompt.userMessage)
val promptWithMemory = Prompt(chatMemory.get(conversationId) + prompt.systemMessage, toolCallingChatOption)
var chatResponse = chatModel.call(promptWithMemory) ?: throw ErrorCode.CHAT_NULL_RESPONSE.toException()
chatMemory.add(conversationId, chatResponse.result.output) // throw Exception
}
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 at JdbcChatMemoryRepository and trace the insert path used for an AssistantMessage containing only toolCalls, then compare it with the provided INSERT statement and the database constraint on content. Reproduce the case with a tool-call-only ChatResponse and verify that the repository handles the message without a SQLIntegrityConstraintViolationException.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, mariadb, sql
- Domain
- database
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100