Skip to content

OpenAiChatModel serializes empty content on assistant tool_call messages, causing 400 #5480

@sammkt005

Description

@sammkt005

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)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions