Repository navigation
FunctionTool automatic parsing fails on list[tuple[bytes, str]] parameter type #5428
Description
🔴 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:
- 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)-
Register the tool on an
LlmAgentand start the agent (e.g. via A2A executor orRunner). -
The agent crashes during
_preprocess_async→_process_agent_tools→tool._get_declaration():
Expected Behavior:
Either:
- ADK should support
tupletypes in function signatures by mapping them to a JSON SchemaarraywithprefixItems, or - ADK should provide a clear, documented mechanism to exclude specific parameters from automatic declaration parsing (e.g., an
ignore_paramsoption onFunctionTool), 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):
- Support
tupletypes in_function_parameter_parse_utilby mapping to JSON SchemaprefixItems. - Expose
ignore_paramsonFunctionTool.__init__(the internal_ignore_paramslist already exists but is not public and only coverstool_context/input_stream). - Add a decorator like
@adk_hiddento mark parameters that should be excluded from the LLM declaration.
Activity
surajksharma07 commentedon Apr 21, 2026
@kaligautier Thanks for the detailed report and for already digging into the root cause — you're right that the fallback path passes a Pydantic-generated schema with prefixItems to types.Schema.model_validate, which rejects it due to extra='forbid'.
As a lighter workaround while the PR is under review, try patching _generate_json_schema_for_parameter to strip prefixItems/unevaluatedItems before validation.
Could you give that a try on your end and confirm it holds up in your Cloud Run setup before we move the PR forward?
kaligautier commentedon Apr 21, 2026
can you give me the snippet ? thx ! @surajksharma07
surajksharma07 commentedon Apr 22, 2026
@kaligautier Drop this before you instantiate your FunctionTool and it'll strip prefixItems/unevaluatedItems from the Pydantic-generated schema before types.Schema sees it:
Also worth a heads-up — PR #5446 just landed from another contributor taking the exact same strip approach but applied directly in the ADK source (_function_parameter_parse_util.py), so there are now two open PRs targeting this.
Once you've confirmed the snippet holds up in Cloud Run, it'd be great if you could drop a note on whichever PR approach you prefer — it'll help the reviewers know where to focus!
Team is looking more into it.
Thanks!
surajksharma07 commentedon May 22, 2026
@kaligautier — since we haven't heard back after sharing the snippet last month and asking you to verify it in your Cloud Run setup, going ahead and closing this out for now to keep things moving.
The underlying fix will continue through the open PRs — your #5429 (fallback tuple handling) and @EaCognitive's #5446 (strip-based approach) are both targeting the same root cause, so reviewers can consolidate from there.
If you do get a chance to test the workaround and confirm it holds, or if you have a preference on which PR approach to push forward, dropping a note on either PR would be really helpful.
Feel free to reopen if anything changes!
fix(tools): handle tuple schemas in function parsing fallback
fix(tools): handle tuple schemas in function parsing fallback