Skip to content

fix(gemini-translator): sanitize stale required entries in OpenAI tool schemas#3864

Closed
myagizmaktav wants to merge 3 commits into
router-for-me:devfrom
myagizmaktav:fix/gemini-tool-required-properties-sanitize
Closed

fix(gemini-translator): sanitize stale required entries in OpenAI tool schemas#3864
myagizmaktav wants to merge 3 commits into
router-for-me:devfrom
myagizmaktav:fix/gemini-tool-required-properties-sanitize

Conversation

@myagizmaktav

Copy link
Copy Markdown

Summary

Fix AI_APICallError: GenerateContentRequest.tools[0].function_declarations[N].parameters.required[M]: property is not defined raised by Gemini API when an OpenAI Chat Completions / Responses tool declares required entries that are missing from properties.

The OpenAI → Gemini translator renamed tools[].function.parameters to parametersJsonSchema but never ran the renamed payload through util.CleanJSONSchemaForGemini. Other translators (claude→gemini, antigravity→gemini) already do so for the same reason. Without that sanitization, cleanupRequiredFields is skipped and every stale required name is forwarded to Gemini, which then rejects the request with the API error above.

Changes

  • internal/translator/gemini/openai/chat-completions/gemini_openai_request.go
    After renaming parametersparametersJsonSchema, run the renamed value through util.CleanJSONSchemaForGemini. This calls cleanupRequiredFields (which intersects required with properties, removing any name that does not have a corresponding property) and also flattens anyOf/oneOf/allOf, removes unsupported keywords, normalizes enums, and strips x-* extension fields — all of which Gemini API rejects.
  • internal/translator/gemini/openai/responses/gemini_openai-responses_request.go
    Same fix for the OpenAI Responses translator.

Tests

New regression tests in:

  • internal/translator/gemini/openai/chat-completions/gemini_openai_request_sanitize_test.go
    • TestConvertOpenAIRequestToGemini_SanitizesStaleRequiredEntries — pins down the original bug.
    • TestConvertOpenAIRequestToGemini_DropsEmptyRequiredArray — confirms the all-stale case is fully removed.
    • TestConvertOpenAIRequestToGemini_AllRequiredValidPassesThrough — guards against regressions in the happy path.
  • internal/translator/gemini/openai/responses/gemini_openai-responses_request_sanitize_test.go
    • TestConvertOpenAIResponsesRequestToGemini_SanitizesStaleRequiredEntries — same coverage for the responses translator.

All tests in the touched packages pass, gofmt is clean, and go build -o test-output ./cmd/server && rm test-output (the AGENTS.md compile guard) succeeds.

Fixes #3863

…l schemas

The OpenAI -> Gemini translator renamed tools[].function.parameters to
parametersJsonSchema but never ran it through CleanJSONSchemaForGemini.
When the OpenAI tool schema declared a 'required' entry that did not
match a key in 'properties' (a common pattern for clients that build
schemas from Pydantic/Zod-style models), the renamed payload reached
Gemini unchanged. Gemini API strictly validates that every name in
required exists in properties, so the request was rejected with:

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

Apply util.CleanJSONSchemaForGemini (which already runs
cleanupRequiredFields, removes unsupported keywords, flattens
anyOf/oneOf/allOf, and normalizes enums) to the renamed
parametersJsonSchema in both the chat-completions and responses
OpenAI->Gemini translators. Add regression tests that pin down the
new behaviour for stale, all-stale, and valid required arrays.
@github-actions github-actions Bot changed the base branch from main to dev June 16, 2026 00:47
@github-actions

Copy link
Copy Markdown

This pull request targeted main.

The base branch has been automatically changed to dev.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces JSON schema sanitization for Gemini API compatibility in both the chat-completions and responses translators, resolving API errors caused by stale required fields. Unit tests are also added to verify the sanitization logic. The review feedback suggests optimizing this process by sanitizing only the nested parameters schema directly rather than the entire function declaration, which reduces performance overhead and avoids potential side effects on non-schema fields.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread internal/translator/gemini/openai/responses/gemini_openai-responses_request.go Outdated
myagizmaktav and others added 2 commits June 16, 2026 03:57
…onses_request.go

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
…ai_request.go

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
@luispater luispater added the wontfix This will not be worked on label Jun 20, 2026
@luispater luispater closed this Jun 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

wontfix This will not be worked on

Projects

None yet

Development

Successfully merging this pull request may close these issues.

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

2 participants