Skip to content

_filter_to_supported_schema crashes with AttributeError: 'bool' object has no attribute 'items' when additionalProperties is a boolean #2476

@dechantoine

Description

@dechantoine

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 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!

Metadata

Metadata

Labels

priority: p2Moderately-important priority. Fix may not be included in next release.type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions