Skip to content

fix(gemini): drop empty enum values from translated schemas - #4688

Open
lyx1311 wants to merge 2 commits into
router-for-me:devfrom
lyx1311:fix/gemini-drop-empty-enum-values
Open

fix(gemini): drop empty enum values from translated schemas#4688
lyx1311 wants to merge 2 commits into
router-for-me:devfrom
lyx1311:fix/gemini-drop-empty-enum-values

Conversation

@lyx1311

@lyx1311 lyx1311 commented Jul 30, 2026

Copy link
Copy Markdown

Problem

Gemini rejects tool/request schemas with:

enum[n]: cannot be empty

(HTTP 400) whenever an enum array contains null or empty string values. This shape is common for optional enums produced by schema generators (for example listing null next to string members). The whole request fails, not just the affected property.

Cause

convertEnumValuesToStrings in internal/util/gemini_schema.go normalizes every enum entry with gjson.Result.String(). For JSON null that returns "", so the empty string is written back into the enum array and forwarded to Gemini, which only accepts non-empty strings there.

Fix

In the current two-arg API convertEnumValuesToStrings(jsonStr, forceStringType):

  • Skip null and empty-string entries while normalizing
  • If nothing valid remains, delete the enum keyword instead of emitting an empty array
  • Preserve order of remaining values
  • Leave forceStringType behavior unchanged (tools still force type: string; response schemas keep declared types)

convertEnumValuesToStrings runs before addEnumHints, so downstream hint text no longer picks up empty values either.

Relation to #4545

This PR implements the same fix intent as #4545 by @RsLuna7, rebased onto the current forceStringType API.

#4545 still targets the older one-arg signature and is currently merge-conflicted (dirty) against dev. This PR is a clean port for maintainers to land without resolving that conflict first. Please close #4545 as superseded if this merges (or the reverse if you prefer cherry-picking from there).

Credit for the original diagnosis and approach: @RsLuna7 / #4545.

Tests

  • TestCleanJSONSchemaRemovesEmptyEnumValues — mixed enum keeps valid values; empty-only enum is removed; covered for Gemini / Antigravity / Antigravity response cleaners
  • TestCleanJSONSchemaForAntigravity_RemovesNullAndEmptyEnumValues — field-shaped nullable enums (todos[].status, capability_mode) matching real tool schemas

Verification

  • gofmt clean on both files
  • go test ./internal/util -count=1 — pass

Production evidence

The same filtering logic was applied on a deployment based on release v7.2.110 (where gemini_schema.go matches current dev for this function). Previously failing requests that returned Gemini enum[n]: cannot be empty (HTTP 400) returned HTTP 200 after the change; Gemini tool-calling paths (gemini-3-flash and related) succeeded end-to-end.

Notes

  • Small, boundary-clear compatibility fix; no protocol surface change beyond dropping invalid enum members Gemini would reject anyway.
  • Scope limited to internal/util/gemini_schema.go + tests.

Gemini rejects enum entries that become empty strings after
gjson null→"" conversion ("enum[n]: cannot be empty"). Filter
null/empty values and delete the enum keyword when nothing valid
remains, preserving forceStringType behavior for tool vs response
schemas.

Field-validated against v7.2.110; ports the approach from router-for-me#4545 onto
the current convertEnumValuesToStrings(jsonStr, forceStringType) API.
@lyx1311
lyx1311 force-pushed the fix/gemini-drop-empty-enum-values branch from e748916 to 447c5d0 Compare August 5, 2026 14:08

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 447c5d0264

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +246 to +248
if len(stringVals) == 0 {
jsonStr, _ = sjson.Delete(jsonStr, p)
continue

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve forced string type when dropping empty enums

In the Gemini/Antigravity tool cleaners forceStringType is true, but this all-invalid branch returns before the type rewrite below. For generated schemas such as {"type":"null","enum":[null]} or {"const":null} (which convertConstToEnum turns into an all-null enum), the cleaner now removes enum and leaves type:"null" or no type instead of the normalized tool-schema string type used for other enum nodes, so these requests can still reach Gemini in an incompatible shape. Please still apply the forced parent type when forceStringType is set before continuing.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Addressed in d5200e5: when all enum values are dropped, still apply forceStringType on the parent type (with tests covering Gemini tool cleaner and Antigravity). Ready for re-review.

When all enum values are null/empty and the enum keyword is removed,
still apply forceStringType for tool cleaners so const:null and
type:null schemas do not leave an incompatible type:null parent.

Addresses Codex review on router-for-me#4688.
@lyx1311

lyx1311 commented Aug 5, 2026

Copy link
Copy Markdown
Author

@codex review

P2 feedback addressed in d5200e5 (force string type when dropping empty enums). Please re-review the latest head.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Hooray!

Reviewed commit: d5200e5d91

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant