spring-projects / spring-projects/spring-ai

OpenAiChatModel serializes empty content on assistant tool_call messages, causing 400

Open
#5,480 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

status: waiting-for-triage
Dominant language
Java
Stars
9.5k
Forks
2.9k
Avg merge
1d 10h
Merged PRs (30d)
5

Description

Bug description

During the multi-turn tool-call loop, OpenAiChatModel.createRequest() serializes
"content":"" (empty string) on assistant messages that carry tool_calls. When
using an OpenAI-compatible backend that proxies to Anthropic/Claude (e.g. Heroku
Inference), the API rejects this with HTTP 400:messages[6]: content is required

OpenAI's own API tolerates "content":"", but Anthropic's API requires content to
be either a non-empty string or null. Since spring-ai-starter-model-openai is
designed to work with any OpenAI-compatible endpoint, the serialization should
produce valid payloads for all compliant backends.

Environment

  • Spring AI: 1.1.2
  • Spring Boot: 3.5.9
  • Java: 17
  • Backend: Heroku Inference (OpenAI-compatible, proxies to Claude-Opus 4-5)

Steps to reproduce

  1. Configure spring-ai-starter-model-openai with an Anthropic-compatible endpoint
  2. Register a @Tool function
  3. Send a user message that triggers the model to call the tool
  4. The model responds with tool_calls and no text content
  5. Spring AI executes the tool locally, then sends the conversation history
    (including the assistant tool_call message) back to the API
  6. HTTP 400: "messages[N]: content is required"

Expected behavior
The assistant message should have "content": null (not "") when the model
response only contained tool calls and no text. Example:

Minimal Complete Reproducible example
{"role":"assistant","content":null,"tool_calls":[{"id":"...","type":"function","function":{"name":"myTool","arguments":"{}"}}]}

Full stack

org.springframework.ai.retry.NonTransientAiException: HTTP 400 - 
{"error":{"code":400,"message":"messages[6]: content is required","type":"invalid_request"}}
  at o.s.ai.retry.autoconfigure.SpringAiRetryAutoConfiguration$2.handleError(SpringAiRetryAutoConfiguration.java:126)
  at o.s.web.client.ResponseErrorHandler.handleError(ResponseErrorHandler.java:58)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at OpenAiChatModel.createRequest and reproduce the multi-turn tool-call flow against an OpenAI-compatible endpoint. Inspect the assistant message produced after a tool call and verify that empty content is serialized as null rather than an empty string. Done means the resulting request matches the provided example and is accepted by the compatible backend.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, spring, spring-boot
Domain
api, backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.