google-gemini / google-gemini/proxy-to-gemini
Issue: Gemini 3 Flash Preview returns 400 "Invalid Argument" when using Function Calling via OpenAI Compatibility API
- Dominant language
- Go
- Stars
- 200
- Forks
- 35
- PR merge metrics
- No merged PRs in 30d
Description
### Description of the bug:
**Description**
Function calling (tool use) works correctly with gemini-2.5-flash but fails with gemini-3-flash-preview when using the OpenAI compatibility API. The model begins processing, outputs thinking content, but when it attempts to call a function, the API most of the time returns a 400 Bad Request error.
**Steps to reproduce**
1. Set up the OpenAI SDK to use Gemini's OpenAI compatibility endpoint
2. Create an Agent with gemini-3-flash-preview model, thinking mode enabled, and a function tool
3. Run the agent with streaming enabled
4. Agent processes the query, begins thinking, then attempts to call the function
5. API returns 400 "Request contains an invalid argument" (30% of the time it would succeed, 70% of the time would return 400 error)
**Code example**
`import os
from openai import AsyncOpenAI
from agents import Agent, ModelSettings, Runner, function_tool, set_default_openai_client, set_default_openai_api
# 1. Setup Gemini client using OpenAI compatibility layer
GEMINI_BASE_URL = "https://generativelanguage.googleapis.com/v1beta/openai/"
client = AsyncOpenAI(api_key=os.environ["GOOGLE_API_KEY"], base_url=GEMINI_BASE_URL)
set_default_openai_client(client)
set_default_openai_api("chat_completions")
# 2. Define a function tool
@function_tool
def get_chart_data(chart_json: str) -> str:
"""Fetches data for a chart configuration and returns it as XML.
Args:
chart_json: JSON string of a chart configuration object
Returns:
XML string containing chart data rows
"""
return ""
# 3. Create agent with gemini-3-flash-preview and thinking mode
agent = Agent(
model="gemini-3-flash-preview", # FAILS - works with "gemini-2.5-flash"
name="chart agent",
instructions="You are a data analyst. Use the get_chart_data tool to fetch chart data.",
tools=[get_chart_data],
model_settings=ModelSettings(
extra_body={
"extra_body": {
"google": {
"thinking_config": {
"thinking_level": high, # for gemini 2.5, I used thinking_budget 24576
}
}
}
}
),
)
# 4. Run the agent with streaming
async def main():
streamed = Runner.run_streamed(agent, [{"role": "user", "content": "Show me sales by month"}])
async for event in streamed.stream_events():
# Error occurs here when model attempts to call the function tool
print(event)
import asyncio
asyncio.run(main())`
Raw output buffer before error shows model was attempting to call the function:
**Stack trace**
Traceback (most recent call last):
File "/var/task/agents/result.py", line 355, in stream_events
raise self._stored_exception
File "/var/task/agents/run.py", line 1204, in _start_streaming
turn_result = await cls._run_single_turn_streamed(
File "/var/task/agents/run.py", line 1446, in _run_single_turn_streamed
async for event in model.stream_response(
File "/var/task/agents/models/openai_chatcompletions.py", line 185, in stream_response
response, stream = await self._fetch_response(
File "/var/task/agents/models/openai_chatcompletions.py", line 321, in _fetch_response
ret = await self._get_client().chat.completions.create(
File "/var/task/openai/resources/chat/completions/completions.py", line 2678, in create
return await self._post(
File "/var/task/openai/_base_client.py", line 1797, in post
return await self.request(cast_to, opts, stream=stream, stream_cls=stream_cls)
File "/var/task/openai/_base_client.py", line 1597, in request
raise self._make_status_error_from_response(err.response) from None
openai.BadRequestError: Error code: 400 - [{'error': {'code': 400, 'message': 'Request contains an invalid argument.', 'status': 'INVALID_ARGUMENT'}}]
Questions
Is function calling supported for gemini-3-flash-preview via the OpenAI compatibility API?
Is there a known incompatibility between thinking mode and function calling for Gemini 3?
### Actual vs expected behavior:
_No response_
### Any other information you'd like to share?
_No response_
Contributor guide
Research direction
The payload names no repository file or test; the relevant entry point is the OpenAI-compatible endpoint exercised by the supplied Python AsyncOpenAI example. Reproduce the streamed function-call request with gemini-3-flash-preview and compare it with gemini-2.5-flash, including thinking settings. Done means the compatibility status and the cause of the 400 response are established, with a verified regression check if a repository-side fix is possible.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, python
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100