Skip to content

fix(gemini): stringify integer enum values in tool schemas#14104

Closed
BSubot wants to merge 1 commit intoNousResearch:mainfrom
BSubot:fix/gemini-integer-enum-stringify
Closed

fix(gemini): stringify integer enum values in tool schemas#14104
BSubot wants to merge 1 commit intoNousResearch:mainfrom
BSubot:fix/gemini-integer-enum-stringify

Conversation

@BSubot
Copy link
Copy Markdown

@BSubot BSubot commented Apr 22, 2026

Summary

Gemini's Schema.enum field strictly requires TYPE_STRING values. When a Hermes tool declares an integer enum (e.g. discord_server's auto_archive_duration=[60, 1440, 4320, 10080]), Gemini rejects the entire request with HTTP 400:

INVALID_ARGUMENT: Invalid value at 'tools[0].function_declarations[N].parameters.properties[M].value.enum[0]' (TYPE_STRING), 60

This happens even when the schema's type is integer — Gemini doesn't coerce. Any subagent routed to a Gemini model with the discord toolset (or any other tool containing integer enums) fails every API call, spamming gateway logs with non-retryable 400s.

Fix

In agent/gemini_schema.sanitize_gemini_schema, coerce every enum value to its str() representation before passing through. Lossless for downstream consumers — Gemini echoes back the string form and the tool dispatcher's JSON argument parsing already coerces integers.

Reproduction (before this PR)

>>> from agent.gemini_schema import sanitize_gemini_schema
>>> sanitize_gemini_schema({"type": "integer", "enum": [60, 1440]})
{'type': 'integer', 'enum': [60, 1440]}   # Gemini rejects this

After:

>>> sanitize_gemini_schema({"type": "integer", "enum": [60, 1440]})
{'type': 'integer', 'enum': ['60', '1440']}   # Gemini accepts

Tests

  • Added tests/agent/test_gemini_schema.py with 6 cases: integer-enum stringification, string-enum preservation, mixed-type enum, nested enum inside properties, enum inside items, and non-list enum dropped.
  • All 95 existing gemini adapter tests (test_gemini_native_adapter.py, test_gemini_cloudcode.py) still pass.
$ pytest tests/agent/test_gemini_schema.py tests/agent/test_gemini_native_adapter.py tests/agent/test_gemini_cloudcode.py -q
101 passed in 1.73s

Notes

  • Only the enum path in sanitize_gemini_schema is touched; behaviour for every other schema key is unchanged.
  • The only in-tree tool affected today is discord_server (tools/discord_tool.py), but the fix is tool-agnostic.

Gemini's Schema.enum field strictly requires TYPE_STRING values. When a
Hermes tool declares an integer enum (e.g. discord_server's
auto_archive_duration=[60, 1440, 4320, 10080]), Gemini rejects the
entire request with HTTP 400:

  INVALID_ARGUMENT: Invalid value at
  'tools[0].function_declarations[N].parameters.properties[M].value.enum[0]'
  (TYPE_STRING), 60

This happens even when the schema's type is 'integer' — Gemini doesn't
coerce. The result is that any subagent routed to a Gemini model with
the discord toolset (or any other tool with integer enums) fails every
API call, spamming gateway logs with non-retryable 400s.

Fix: in agent/gemini_schema.sanitize_gemini_schema, coerce every enum
value to its str() representation before passing through. This is
lossless for downstream consumers — Gemini echoes back the string form,
and the tool dispatcher parses arguments from the model's JSON output
where integer coercion already happens.

Tests:
- 6 new unit tests in tests/agent/test_gemini_schema.py covering
  integer, string, mixed, nested, items, and non-list enum cases
- All 95 existing gemini adapter tests still pass
@alt-glitch alt-glitch added type/bug Something isn't working P1 High — major feature broken, no workaround comp/agent Core agent loop, run_agent.py, prompt builder provider/gemini Google Gemini (AI Studio, Cloud Code) labels Apr 22, 2026
@alt-glitch
Copy link
Copy Markdown
Collaborator

Likely duplicate of #13486 — same root cause: integer enum in tool schema breaks Gemini. This PR fixes it in sanitize_gemini_schema rather than in the tool definition.

@alt-glitch
Copy link
Copy Markdown
Collaborator

Duplicate of #13486.

@andersmmg
Copy link
Copy Markdown

This seems like a better solution than the others, since it can cover other cases if they arise or are discovered, rather than requiring changes to the tools themselves

@teknium1
Copy link
Copy Markdown
Contributor

Thanks for the thorough write-up and reproduction steps, @BSubot — this is a real bug and the fix direction is correct.

This is an automated hermes-sweeper review.

The same root cause was addressed on main one day after this PR was opened:

  • Commit: 1f9c36862fix(gemini): drop integer/number/boolean enums from tool schemas (PR fix(gemini): drop integer/number/boolean enums from tool schemas #15082, merged 2026-04-24)
  • File: agent/gemini_schema.pysanitize_gemini_schema now strips the enum key when type is integer/number/boolean and any entry is non-string
  • Tests: tests/agent/test_gemini_schema.py was added in the same commit with overlapping coverage (integer enum drop, number enum, boolean enum, string enum preservation)

The landed fix uses a drop strategy rather than stringify — the type + description fields remain so the model still understands the valid values, avoiding any coercion ambiguity. This resolves the INVALID_ARGUMENT: TYPE_STRING 400s for Discord's auto_archive_duration and any other tool with non-string enums.

Closing as implemented on main. The referenced issue #13486 can be closed separately.

@teknium1 teknium1 closed this Apr 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent loop, run_agent.py, prompt builder P1 High — major feature broken, no workaround provider/gemini Google Gemini (AI Studio, Cloud Code) type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants