Skip to content

fix: strip unsupported JSON Schema fields for Google GenAI provider#1466

Closed
Br1an67 wants to merge 1 commit intoMoonshotAI:mainfrom
Br1an67:fix/google-genai-strip-schema
Closed

fix: strip unsupported JSON Schema fields for Google GenAI provider#1466
Br1an67 wants to merge 1 commit intoMoonshotAI:mainfrom
Br1an67:fix/google-genai-strip-schema

Conversation

@Br1an67
Copy link

@Br1an67 Br1an67 commented Mar 17, 2026

Problem

When MCP tools provide standard JSON Schema parameters containing metadata fields like $schema, the google-genai SDK's Pydantic model rejects them with extra_forbidden validation errors, preventing tool calls.

Fix

Strip unsupported JSON Schema metadata fields ($schema, $id, $ref, $comment, definitions, $defs) from tool parameters in tool_to_google_genai() before passing to the SDK.

Fixes #734


Open with Devin

Copy link

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

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: 57c01c7894

ℹ️ 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 +361 to +362
unsupported_keys = {"$schema", "$id", "$ref", "$comment", "definitions", "$defs"}
parameters = {k: v for k, v in parameters.items() if k not in unsupported_keys}

Choose a reason for hiding this comment

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

P1 Badge Preserve referenced sub-schemas when stripping metadata

Filtering out top-level definitions/$defs here can invalidate otherwise valid tool schemas, because nested properties may still contain $ref pointers to those removed definitions (a common shape for nested Pydantic/JSON-Schema models). In that case the provider receives a dangling-reference schema and tool declarations can be rejected or lose parameter structure, so tool calling still breaks for nested parameter types.

Useful? React with 👍 / 👎.

devin-ai-integration[bot]

This comment was marked as resolved.

When MCP tools provide standard JSON Schema parameters containing
metadata fields like $schema, the google-genai SDK's Pydantic
model rejects them with extra_forbidden validation errors.

Use the existing deref_json_schema() utility to properly resolve
$ref entries and remove $defs/definitions, preserving nested
parameter types. Then strip remaining metadata fields ($schema,
$id, $comment) that the SDK doesn't support.

Fixes MoonshotAI#734
@Br1an67 Br1an67 force-pushed the fix/google-genai-strip-schema branch from 57c01c7 to 779c349 Compare March 17, 2026 07:19
Copy link

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

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: 779c349629

ℹ️ 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".

# nested parameter types are preserved instead of becoming dangling refs
from kosong.utils.jsonschema import deref_json_schema

parameters = deref_json_schema(parameters)

Choose a reason for hiding this comment

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

P1 Badge Guard against recursive $ref schemas

Calling deref_json_schema() unconditionally here can crash tool conversion for valid self-referential schemas (for example MCP tools that model tree/graph inputs), because the resolver recursively inlines local $ref targets without cycle detection and will recurse forever on references like "$ref": "#"/mutual refs. In that case tool_to_google_genai() now raises before the request is sent, whereas this path previously passed the schema through, so Google provider tool calls regress from "SDK may reject" to a hard local failure.

Useful? React with 👍 / 👎.

Copy link
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 1 new potential issue.

View 4 additional findings in Devin Review.

Open in Devin Review

Comment on lines +366 to +367
unsupported_keys = {"$schema", "$id", "$comment"}
parameters = {k: v for k, v in parameters.items() if k not in unsupported_keys}
Copy link
Contributor

Choose a reason for hiding this comment

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

🟡 Unsupported JSON Schema keys only stripped at top level, not recursively

The stripping of keys rejected by the Google GenAI SDK ($schema, $id, $comment) is applied only to the top-level of parameters via a shallow dict comprehension at line 367. If any nested schema object (e.g., inside properties, items, allOf, etc.) contains these keys, they will remain and still trigger the extra_forbidden validation error from the SDK's Pydantic model — the same error this code intends to fix.

Example: nested $comment survives stripping

A tool with parameters like:

{"type": "object", "$comment": "top-level", "properties": {"x": {"type": "string", "$comment": "nested"}}}

After line 367, the top-level $comment is removed, but properties.x.$comment remains, causing the same SDK validation error.

While $schema is conventionally top-level only, $comment is valid at any nesting depth per the JSON Schema spec, and tool parameter schemas from MCP tools or other non-Pydantic sources could include it at nested levels.

Prompt for agents
In packages/kosong/src/kosong/contrib/chat_provider/google_genai.py, the tool_to_google_genai function (around lines 353-376) strips unsupported keys ($schema, $id, $comment) only at the top level of the parameters dict (line 367). This should be done recursively to also strip these keys from nested schema objects. Consider adding a helper function like:

def _strip_unsupported_keys(schema: dict) -> dict:
    unsupported_keys = {"$schema", "$id", "$comment"}
    result = {k: v for k, v in schema.items() if k not in unsupported_keys}
    for key, value in result.items():
        if isinstance(value, dict):
            result[key] = _strip_unsupported_keys(value)
        elif isinstance(value, list):
            result[key] = [
                _strip_unsupported_keys(item) if isinstance(item, dict) else item
                for item in value
            ]
    return result

Then replace lines 366-367 with: parameters = _strip_unsupported_keys(parameters)
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@Br1an67
Copy link
Author

Br1an67 commented Mar 17, 2026

Closing this PR — the issue was independently fixed on main via commit 45333f0 which uses parameters_json_schema to bypass the SDK's Pydantic validation entirely. This is a cleaner approach than schema manipulation.

@Br1an67 Br1an67 closed this Mar 17, 2026
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.

[Bug]: Google GenAI provider fails with extra_forbidden for tool parameters containing $schema

1 participant