-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Open
Copy link
Labels
mcp[Component] Issues about MCP support[Component] Issues about MCP supporttools[Component] This issue is related to tools[Component] This issue is related to tools
Description
Describe the bug
The _to_gemini_schema() function in google.adk.tools._gemini_schema_util triggers a RecursionError when processing JSON Schemas with circular $ref references in $defs. The _dereference_schema() helper function recursively resolves these references without detecting circular dependencies, causing infinite recursion.
To Reproduce
- Minimal code to reproduce the issue:
from google.adk.tools._gemini_schema_util import _to_gemini_schema # Schema with circular reference: Attendee -> alternateAttendee -> Attendee schema_with_circular_refs = { "type": "object", "properties": { "body": { "type": "object", "properties": { "attendees": { "type": "array", "items": {"$ref": "#/$defs/Attendee"} }, "end": {"$ref": "#/$defs/DateTimeTimeZone"} } } }, "$defs": { "DateTimeTimeZone": { "type": "object", "properties": { "dateTime": {"type": "string"}, "timeZone": {"type": "string"} } }, "Attendee": { "type": "object", "properties": { "proposedNewTime": { "type": "object", "properties": { "start": {"$ref": "#/$defs/DateTimeTimeZone"}, "end": {"$ref": "#/$defs/DateTimeTimeZone"} } }, "alternateAttendee": {"$ref": "#/$defs/Attendee"} } } }, "required": ["body"] } # This will trigger a RecursionError gemini_schema = _to_gemini_schema(schema_with_circular_refs) - Steps to reproduce:
- Install
google-adkandgoogle-genai - Run the code above
- Observe
RecursionError: maximum recursion depth exceeded
- Install
Expected behavior
-
The function should either:
- Detect circular references and raise a clear, descriptive error (e.g., ValueError: Circular reference detected in schema at path ...)
- Handle circular references gracefully by tracking visited definitions during dereferencing
-
Stack trace:
[...] File "/home/ubuntu/venv/lib/python3.12/site-packages/google/adk/tools/_gemini_schema_util.py", line 94, in _resolve_refs return _resolve_refs(resolved) ^^^^^^^^^^^^^^^^^^^^^^^ File "/home/ubuntu/venv/lib/python3.12/site-packages/google/adk/tools/_gemini_schema_util.py", line 100, in _resolve_refs return {key: _resolve_refs(value) for key, value in sub_schema.items()} ^^^^^^^^^^^^^^^^^^^^ File "/home/ubuntu/venv/lib/python3.12/site-packages/google/adk/tools/_gemini_schema_util.py", line 100, in _resolve_refs return {key: _resolve_refs(value) for key, value in sub_schema.items()} ^^^^^^^^^^^^^^^^^^^^ File "/home/ubuntu/venv/lib/python3.12/site-packages/google/adk/tools/_gemini_schema_util.py", line 94, in _resolve_refs return _resolve_refs(resolved) ^^^^^^^^^^^^^^^^^^^^^^^ File "/home/ubuntu/venv/lib/python3.12/site-packages/google/adk/tools/_gemini_schema_util.py", line 100, in _resolve_refs return {key: _resolve_refs(value) for key, value in sub_schema.items()} ^^^^^^^^^^^^^^^^^^^^ File "/home/ubuntu/venv/lib/python3.12/site-packages/google/adk/tools/_gemini_schema_util.py", line 100, in _resolve_refs return {key: _resolve_refs(value) for key, value in sub_schema.items()} ^^^^^^^^^^^^^^^^^^^^ File "/home/ubuntu/venv/lib/python3.12/site-packages/google/adk/tools/_gemini_schema_util.py", line 94, in _resolve_refs return _resolve_refs(resolved) ^^^^^^^^^^^^^^^^^^^^^^^ File "/home/ubuntu/venv/lib/python3.12/site-packages/google/adk/tools/_gemini_schema_util.py", line 100, in _resolve_refs return {key: _resolve_refs(value) for key, value in sub_schema.items()} ^^^^^^^^^^^^^^^^^^^^ File "/home/ubuntu/venv/lib/python3.12/site-packages/google/adk/tools/_gemini_schema_util.py", line 100, in _resolve_refs return {key: _resolve_refs(value) for key, value in sub_schema.items()} ^^^^^^^^^^^^^^^^^^^^ File "/home/ubuntu/venv/lib/python3.12/site-packages/google/adk/tools/_gemini_schema_util.py", line 100, in _resolve_refs return {key: _resolve_refs(value) for key, value in sub_schema.items()} ^^^^^^^^^^^^^^^^^^^^ [Previous line repeated 1 more time] File "/home/ubuntu/venv/lib/python3.12/site-packages/google/adk/tools/_gemini_schema_util.py", line 94, in _resolve_refs return _resolve_refs(resolved) ^^^^^^^^^^^^^^^^^^^^^^^ File "/home/ubuntu/venv/lib/python3.12/site-packages/google/adk/tools/_gemini_schema_util.py", line 100, in _resolve_refs return {key: _resolve_refs(value) for key, value in sub_schema.items()} ^^^^^^^^^^^^^^^^^^^^ File "/home/ubuntu/venv/lib/python3.12/site-packages/google/adk/tools/_gemini_schema_util.py", line 100, in _resolve_refs return {key: _resolve_refs(value) for key, value in sub_schema.items()} ^^^^^^^^^^^^^^^^^^^^ RecursionError: maximum recursion depth exceeded
Desktop (please complete the following information):
- OS: Linux (Ubuntu)
- Python version(python -V): Python 3.12.3
- ADK version(pip show google-adk):
google-adk==1.20.0google-genai==1.54.0
Model Information:
- Are you using LiteLLM: No
- Which model is being used(e.g. gemini-2.5-pro): N/A (error occurs during schema conversion, before model invocation)
Additional Context
This issue was discovered while building an MCP server tool that uses schemas with legitimate circular references for recursive data structures (for example, attendees with alternate attendees)
- The root cause appears to be in
_dereference_schema(), which currently does not perform cycle detection when recursively resolving$refpointers in$defs - A previous attempt was made to fix this in
google-genai, but that change could not be merged because the affected file (types.py) is dynamically generated - I was advised to raise an issue (and potentially a PR) here; once I figure out an appropriate approach, I am happy to follow up with a PR
rkrumins
Metadata
Metadata
Assignees
Labels
mcp[Component] Issues about MCP support[Component] Issues about MCP supporttools[Component] This issue is related to tools[Component] This issue is related to tools