Skip to content

FunctionTool automatic parsing fails on list[tuple[bytes, str]] parameter type #5428

@kaligautier

Description

@kaligautier

🔴 Required Information

Describe the Bug:
FunctionTool automatic function declaration parsing crashes at startup when a tool function has a parameter typed list[tuple[bytes, str]] | None. The error originates from _function_parameter_parse_util._raise_for_unsupported_param after Pydantic's Schema.model_validate rejects the generated schema with Extra inputs are not permitted.

This prevents the agent from starting entirely — it's not a runtime error but a startup crash during tool declaration building.

Steps to Reproduce:

  1. Define a tool function with a complex parameter type:
from google.adk.tools import ToolContext
from google.adk.tools.function_tool import FunctionTool

async def generate_image(
    prompt: str,
    input_bytes: list[tuple[bytes, str]] | None = None,
    tool_context: ToolContext = None,
) -> dict:
    """Generate an image from a prompt."""
    return {"status": "success"}

generate_image_tool = FunctionTool(func=generate_image)
  1. Register the tool on an LlmAgent and start the agent (e.g. via A2A executor or Runner).

  2. The agent crashes during _preprocess_async_process_agent_toolstool._get_declaration():

Expected Behavior:
Either:

  • ADK should support tuple types in function signatures by mapping them to a JSON Schema array with prefixItems, or
  • ADK should provide a clear, documented mechanism to exclude specific parameters from automatic declaration parsing (e.g., an ignore_params option on FunctionTool), or
  • At minimum, the error message should link to documentation on how to implement the manual declaration workaround.

Observed Behavior:
Two chained exceptions:

pydantic_core._pydantic_core.ValidationError: 1 validation error for Schema
  Extra inputs are not permitted [type=extra_forbidden, input_value=[{'format': 'binary', 'ty...g'}, {'type': 'string'}], input_type=list]

Followed by:

ValueError: Failed to parse the parameter input_bytes: list[tuple[bytes, str]] | None = None
of function generate_image for automatic function calling.
Automatic function calling works best with simpler function signature schema,
consider manually parsing your function declaration for function generate_image.

Environment Details:

  • ADK Library Version: 1.26.0
  • Desktop OS: Linux (Cloud Run container) / macOS (local dev)
  • Python Version: 3.12

Model Information:

  • Are you using LiteLLM: No
  • Which model is being used: Gemini (via Vertex AI)

🟡 Optional Information

Regression:
N/A — first time using this parameter type.

Logs:

File "/app/.venv/lib/python3.12/site-packages/google/adk/tools/function_tool.py", line 89, in _get_declaration
    build_function_declaration(
  File "/app/.venv/lib/python3.12/site-packages/google/adk/tools/_automatic_function_calling_util.py", line 257, in build_function_declaration
    else from_function_with_options(new_func, variant)
  File "/app/.venv/lib/python3.12/site-packages/google/adk/tools/_automatic_function_calling_util.py", line 368, in from_function_with_options
    _function_parameter_parse_util._raise_for_unsupported_param(
  File "/app/.venv/lib/python3.12/site-packages/google/adk/tools/_function_parameter_parse_util.py", line 101, in _raise_for_unsupported_param
    raise ValueError(
ValueError: Failed to parse the parameter input_bytes: list[tuple[bytes, str]] | None = None of function generate_image

How often has this issue occurred?:

  • Always (100%)

Additional Context:

The use case is an image generation tool where a before_tool callback pre-loads remote images (from GCS, Google Drive, or artifacts) and injects the loaded (bytes, mime_type) pairs into the function args. The LLM never fills these parameters — they are only set programmatically by the callback.

Current workaround: Subclass FunctionTool, override _get_declaration() to return a hand-crafted types.FunctionDeclaration that only exposes LLM-visible parameters (prompt, aspect_ratio, etc.) and omits input_bytes from the schema entirely. This works but is verbose and error-prone.

Suggested improvements (any of):

  1. Support tuple types in _function_parameter_parse_util by mapping to JSON Schema prefixItems.
  2. Expose ignore_params on FunctionTool.__init__ (the internal _ignore_params list already exists but is not public and only covers tool_context/input_stream).
  3. Add a decorator like @adk_hidden to mark parameters that should be excluded from the LLM declaration.

Metadata

Metadata

Labels

request clarification[Status] The maintainer need clarification or more information from the authortools[Component] This issue is related to tools

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions