Skip to content

Bug: Gemini API rejects OpenAI tools with stale 'required' entries (parameters.required[].property is not defined) #3863

Description

@myagizmaktav

Summary

When a client sends an OpenAI Chat Completions or Responses request that includes a tool whose parameters.required array lists fields that do not exist in the parameters.properties map, the proxy forwards the request to Gemini unchanged, and Gemini API rejects it with:

AI_APICallError: GenerateContentRequest.tools[0].function_declarations[N].parameters.required[M]: property is not defined

Reproduction

curl -X POST http://localhost:<port>/v1/chat/completions \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "gemini-2.0-flash",
    "messages": [{"role":"user","content":"hi"}],
    "tools": [{
      "type": "function",
      "function": {
        "name": "search_company",
        "description": "Search",
        "parameters": {
          "type": "object",
          "properties": {"country":{"type":"string"},"industry":{"type":"string"}},
          "required": ["country","industry","stale_field","another_stale"]
        }
      }
    }]
  }'

Expected behavior

The proxy should strip the stale required entries before forwarding, since util.CleanJSONSchemaForGemini already implements cleanupRequiredFields for exactly this case. The OpenAI spec is lenient about required (some clients add a name and forget to define the property, or generate schemas from Pydantic/Zod models that include intermediate/aliased fields), so the request is valid upstream of the proxy. Gemini, however, is strict.

Root cause

In internal/translator/gemini/openai/chat-completions/gemini_openai_request.go (and the responses counterpart), the code renames tools[].function.parameters to parametersJsonSchema but does not run the renamed payload through util.CleanJSONSchemaForGemini. Other translators (claude->gemini, antigravity->gemini) already do so for the same reason. Without that sanitization step:

  • cleanupRequiredFields is skipped, so any name in required that is missing from properties is forwarded as-is.
  • Other Gemini-incompatible keywords (const, $ref, patternProperties, x-* extensions, numeric enums, etc.) leak through too.

Proposed fix

Run util.CleanJSONSchemaForGemini on the renamed parametersJsonSchema after the rename, in both translators. This is the same fix shape already used by the claude and antigravity translators.

A draft implementation lives on fix/gemini-tool-required-properties-sanitize in myagizmaktav/CLIProxyAPI. PR incoming.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions