You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[legacy path] Nested pydantic model tool parameter fails under VERTEX_AI when the function also has a fallback-parsed parameter — only with JSON_SCHEMA_FOR_FUNC_DECL disabled #6984
Update (2026-09-03): Scope corrected — this only affects the legacy declaration path, i.e. when JSON_SCHEMA_FOR_FUNC_DECL is disabled. Default FunctionTool usage is not affected. See my comment below for the end-to-end reproduction.
🔴 Required Information
Describe the Bug:
When a tool function has a parameter that the strict parser in _function_parameter_parse_util does not handle (e.g. datetime.datetime), from_function_with_options falls back to building each parameter's schema from pydantic's JSON schema. In that fallback, the GEMINI_API variant runs _sanitize_schema_formats_for_gemini (which, among other things, turns $ref/$defs into ref/defs), but the VERTEX_AI variant validates the raw JSON schema directly with types.Schema.model_validate. Any nested pydantic model parameter therefore fails on Vertex with $ref / $defsextra_forbidden errors, and the surfaced ValueError blames that (valid) model parameter rather than the parameter that triggered the fallback.
Net effect: the same tool works on the Gemini Developer API but cannot be registered on Vertex AI.
Steps to Reproduce:
pip install google-adk
Run the snippet under Minimal Reproduction Code
Expected Behavior:
Both variants produce a declaration; on Vertex, p is described as an object with nested addr (the GEMINI_API variant already emits defs/ref for it).
Observed Behavior:
GEMINI_API: True
...
pydantic_core._pydantic_core.ValidationError: 2 validation errors for Schema
properties.addr.$ref
Extra inputs are not permitted [type=extra_forbidden, input_value='#/$defs/Addr', input_type=str]
$defs
Extra inputs are not permitted [type=extra_forbidden, ...]
...
ValueError: Failed to parse the parameter p: __main__.Person of function schedule for automatic function calling. ...
Environment Details:
ADK Library Version (pip show google-adk): 2.8.0 (also reproduces on main)
Desktop OS: macOS (arm64)
Python Version (python -V): 3.14.7
Model Information:
Are you using LiteLLM: No
Which model is being used: N/A (reproduces at declaration-build time; variant selected explicitly via from_function_with_options(func, GoogleLLMVariant.VERTEX_AI))
🟡 Optional Information
Regression:
Unknown.
Logs:
See Observed Behavior above.
Screenshots / Video:
N/A
Additional Context:
The nested model alone (no fallback-triggering parameter) works on both variants, because the strict parser handles BaseModel recursively; the failure needs the function to enter the pydantic fallback path.
🔴 Required Information
Describe the Bug:
When a tool function has a parameter that the strict parser in
_function_parameter_parse_utildoes not handle (e.g.datetime.datetime),from_function_with_optionsfalls back to building each parameter's schema from pydantic's JSON schema. In that fallback, theGEMINI_APIvariant runs_sanitize_schema_formats_for_gemini(which, among other things, turns$ref/$defsintoref/defs), but theVERTEX_AIvariant validates the raw JSON schema directly withtypes.Schema.model_validate. Any nested pydantic model parameter therefore fails on Vertex with$ref/$defsextra_forbiddenerrors, and the surfacedValueErrorblames that (valid) model parameter rather than the parameter that triggered the fallback.Net effect: the same tool works on the Gemini Developer API but cannot be registered on Vertex AI.
Steps to Reproduce:
pip install google-adkExpected Behavior:
Both variants produce a declaration; on Vertex,
pis described as an object with nestedaddr(theGEMINI_APIvariant already emitsdefs/reffor it).Observed Behavior:
Environment Details:
main)Model Information:
from_function_with_options(func, GoogleLLMVariant.VERTEX_AI))🟡 Optional Information
Regression:
Unknown.
Logs:
See Observed Behavior above.
Screenshots / Video:
N/A
Additional Context:
BaseModelrecursively; the failure needs the function to enter the pydantic fallback path.anyOfflattening in_function_tool_declarations.py, but the fallback path in_automatic_function_calling_util.from_function_with_optionshas no$ref/$defshandling forVERTEX_AI.Minimal Reproduction Code:
How often has this issue occurred?: