googleapis / googleapis/python-genai
_filter_to_supported_schema crashes with AttributeError: 'bool' object has no attribute 'items' when additionalProperties is a boolean
- Dominant language
- Python
- Stars
- 4k
- Forks
- 1k
- Avg merge
- 2d 11h
- Merged PRs (30d)
- 40
Description
Hey there! 👋
First off, love the work on MCP support in google-genai ! I ran into a small regression introduced in 8c00c52 that I wanted to flag, along with a minimal repro and a proposed fix. Hope this helps!
#### Environment details
- Programming language: Python
- OS: MacOS Tahoe 26.4.1
- Language runtime version: Python 3.14
- Package version: 2.1.0
#### Steps to reproduce
What's happening?
When using a MCP server built with https://github.com/PrefectHQ/fastmcp (and likely other MCP SDKs), calling _filter_to_supported_schema on a tool's inputSchema crashes with:
`AttributeError: 'bool' object has no attribute 'items'`
The culprit is "additionalProperties": false; a totally valid JSON Schema field that FastMCP includes by default.
The code introduced in [8c00c52](https://github.com/googleapis/python-genai/commit/8c00c524488250f25f497e47b495dcedb362da86) assumes this field is always a dict (a nested sub-schema), but per the https://json-schema.org/understanding-json-schema/reference/object#additionalproperties, it can also be a boolean.
Steps to reproduce
```
from fastmcp import Client, FastMCP
from google.genai import types, _extra_utils, _mcp_utils
mcp = FastMCP('test_mcp')
@mcp.tool(name="test-func")
async def test_func(arg1: str, arg2: int) -> str:
return f"Received arg1: {arg1} and arg2: {arg2}"
client = Client(mcp)
async def main():
async with client:
config = types.GenerateContentConfig(
tools=[client.session],
)
parsed_config = _extra_utils.parse_config_for_mcp_usage(config)
mcp_to_genai_tool_adapter = _extra_utils.McpToGenAiToolAdapter(
parsed_config.tools[0], await parsed_config.tools[0].list_tools()
)
# This crashes:
tools = _mcp_utils.mcp_to_gemini_tool(mcp_to_genai_tool_adapter._list_tools_result.tools[0])
```
FastMCP generates this inputSchema for the tool above — nothing exotic, just standard JSON Schema:
```
{
"type": "object",
"properties": {
"arg1": { "type": "string" },
"arg2": { "type": "integer" }
},
"required": ["arg1", "arg2"],
"additionalProperties": false
}
```
---
Full traceback
```
File "../google/genai/_mcp_utils.py", line 47, in mcp_to_gemini_tool
**_filter_to_supported_schema(tool.inputSchema)
~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^
File "../genai/_mcp_utils.py", line 132, in _filter_to_supported_schema
filtered_schema[field_name] = _filter_to_supported_schema(field_value)
~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^
File "../google/genai/_mcp_utils.py", line 130, in _filter_to_supported_schema
for field_name, field_value in schema.items():
^^^^^^^^^^^^
AttributeError: 'bool' object has no attribute 'items'
```
---
Root cause
In 8c00c52, "additionalProperties" was added to schema_field_names — the tuple of fields whose values get recursed into as nested schemas:
```
schema_field_names = (
"items",
"additionalProperties", # ← added here
"additional_properties", # ← and here
)
...
for field_name, field_value in schema.items():
if field_name in schema_field_names:
filtered_schema[field_name] = _filter_to_supported_schema(field_value)
# ☝️ crashes when field_value is `False`!
```
Since the code always recurses into additionalProperties, it fails when the value is a boolean instead of a dict.
---
Proposed fix
Just add an isinstance(field_value, dict) guard before recursing — booleans pass through as-is:
```
for field_name, field_value in schema.items():
if field_name in schema_field_names and isinstance(field_value, dict):
filtered_schema[field_name] = _filter_to_supported_schema(field_value)
elif field_name in schema_field_names:
filtered_schema[field_name] = field_value # booleans are valid, keep them!
elif field_name in list_schema_field_names:
...
```
I will open a PR with this fix, hope that would be helpful!
Contributor guide
Assessment
This issue has not been assessed yet.