Skip to content

fix: populate required fields in FunctionDeclaration json_schema fallback#5000

Open
giulio-leone wants to merge 2 commits intogoogle:mainfrom
giulio-leone:fix/required-fields-json-schema-fallback
Open

fix: populate required fields in FunctionDeclaration json_schema fallback#5000
giulio-leone wants to merge 2 commits intogoogle:mainfrom
giulio-leone:fix/required-fields-json-schema-fallback

Conversation

@giulio-leone
Copy link

Summary

Fixes #4798required fields lost in FunctionDeclaration when the parameters_json_schema fallback path is used.

Root Cause

from_function_with_options() has two code paths for building function declarations:

  1. Primary path (parameters_properties): calls _get_required_fields()
  2. Fallback path (parameters_json_schema): triggered when _parse_schema_from_parameter raises ValueError for complex union types (e.g. list[str] | None) — never called _get_required_fields()

Additionally, the fallback path didn't propagate default values from inspect.Parameter to the generated Schema, so _get_required_fields() (which checks schema.default is None) would treat defaulted parameters as required.

Impact

The LLM sees all parameters as optional and may omit required ones. Observed in production: Gemini Flash omitted the mandatory query parameter when calling a tool, because the schema had no required field.

Fix

Three changes to the elif parameters_json_schema branch in from_function_with_options():

Change Purpose
Added _get_required_fields() call Populates required field (mirrors primary path)
Propagate non-None defaults to schema.default Ensures _get_required_fields() correctly excludes defaulted params
Set schema.nullable=True for None-default params Ensures _get_required_fields() correctly excludes nullable params

Test

Added regression test test_required_fields_set_in_json_schema_fallback that verifies:

  • query (no default) → required ✅
  • mode (default='default') → not required ✅
  • tags: list[str] | None = None → not required ✅

Full test suite: 4726 passed, 0 failures

⚠️ This reopens #4812 which was accidentally closed due to fork deletion.

…back

When _parse_schema_from_parameter raises ValueError for complex union
types (e.g. list[str] | None), from_function_with_options falls back to
the parameters_json_schema branch. This branch was missing two things:

1. The _get_required_fields() call to populate declaration.parameters.required
2. Default value propagation from inspect.Parameter to Schema.default/nullable

Without these, the LLM sees all parameters as optional and may omit
required ones.

This fix:
- Adds _get_required_fields() to the elif branch (mirrors primary path)
- Propagates non-None defaults to schema.default
- Sets schema.nullable=True for parameters defaulting to None

Includes regression test with list[str] | None parameter type.

Fixes google#4798
Clear the pyink failure on PR google#4812 after validating the json_schema fallback behavior with targeted pytest and a runtime reproduction script.
@adk-bot adk-bot added the tools [Component] This issue is related to tools label Mar 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

tools [Component] This issue is related to tools

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: required fields lost in FunctionDeclaration when parameters_json_schema fallback is used

2 participants