2. Issue Summary for Google Gemini API Forum/Tracker:
Subject: BadRequestError
(function_response.name
empty) when replying to tool_calls
with empty id
via OpenAI Compatibility Layer
Environment:
- API Endpoint: Google Generative Language API (via OpenAI Compatibility Layer -
https://generativelanguage.googleapis.com/v1beta/openai/
) - Model:
gemini-2.5-pro-exp-03-25
(or specify your model) - Library:
openai
Python library (specify version, e.g.,v1.16.1
) - Language: Python 3.10
Problem Description:
When using the OpenAI Python library to interact with Gemini models via the compatibility endpoint, if the model returns a tool_calls
response where the id
field is an empty string (id: ''
), the subsequent attempt to send the corresponding tool result back to the API fails.
Steps to Reproduce:
- Send a chat completion request with tools defined (
client.chat.completions.create
). - Receive a response from the Gemini model containing a
tool_calls
block wheretool_calls[0].id == ''
. - Execute the requested tool locally.
- Construct the message history for the next API call, including:
- The original messages.
- The assistant message containing the
tool_calls
block (with the emptyid
). - A new message with
role: 'tool'
, providing atool_call_id
(e.g., a placeholder like'unknown_id_...'
or even the empty string''
), the correctname
of the function, and the stringifiedcontent
result.
- Send this updated message history back to the chat completions endpoint.
Observed Behavior:
The second API call fails with a openai.BadRequestError
(HTTP 400). The error message reported by the API is:
* GenerateContentRequest.contents[3].parts[0].function_response.name: Name cannot be empty.
(Note: The index [3]
might vary but points towards the role: tool
message)
Expected Behavior:
The API should accept the role: tool
message, ideally matching it via the name
or gracefully handling the empty id
from its own previous response, allowing the conversation to proceed.
Evidence/Debugging:
- Logs confirm the
tool_calls
block received from the first API call containsid: ''
. - Deep debugging logs (injecting logging into the
openai
library’s_base_client.py
) confirm that themessages
list being sent in the second (failing) API call does contain therole: 'tool'
message with the correct, non-emptyname
field populated. - Despite the
name
field being present in the payload constructed by the library, the Google endpoint still rejects it, claiming thename
is empty.
Workaround:
The current workaround is to detect tool_calls
with empty IDs in the application layer and skip sending the corresponding role: tool
message back to the API. This prevents the BadRequestError
but breaks the tool-use flow for that turn.
Request:
Could the Gemini team investigate why the OpenAI compatibility endpoint rejects validly formed role: tool
messages (containing the required name
) when they correspond to an initial tool_calls
request that had an empty id
? Is the empty id
the expected behavior, and if so, how should clients correctly reply with tool results in this scenario using the OpenAI message format?