Skip to content

Python: preserve explicit null arguments in auto function calling#7108

Open
he-yufeng wants to merge 1 commit into
microsoft:mainfrom
he-yufeng:fix/tool-null-args-5934
Open

Python: preserve explicit null arguments in auto function calling#7108
he-yufeng wants to merge 1 commit into
microsoft:mainfrom
he-yufeng:fix/tool-null-args-5934

Conversation

@he-yufeng

Copy link
Copy Markdown
Contributor

Description

Fixes #5934.

FunctionTool.invoke dumped the validated arguments with model_dump(exclude_none=True), which strips any argument whose value is null. When the model deliberately sets a required nullable parameter to null — e.g. unit: Literal["C", "F"] | None with a description telling the model to set it to null when the user gave no unit — that argument was dropped, and the function then failed to invoke on the missing required argument.

The fix uses exclude_unset=True instead: keep the arguments the model actually provided (an explicit null included) and omit only the ones it left out, so the function's own defaults still apply. Because the tool's input model is generated from the function signature, its field defaults match the signature defaults, so omitted optionals behave exactly as before — only explicitly-provided nulls are now preserved.

Changed both the mapping path (the auto-function-calling path from the model) and the BaseModel path for consistency.

Behavior

For a required nullable parameter the model sets to null:

before (exclude_none):  unit dropped -> TypeError: missing required argument 'unit'
after  (exclude_unset): unit=None passed through -> function runs

An omitted optional argument still falls back to the function's own default (unchanged).

Tests

Adds test_invoke_preserves_explicit_null_argument (the #5934 repro, fails against the old behavior) and test_invoke_omitted_optional_uses_function_default (guards that omitted optionals still use the function default).

FunctionTool.invoke dumped validated arguments with model_dump(exclude_none=True),
which strips any argument the model set to null. A required nullable parameter
(e.g. unit: Literal["C","F"] | None) that the model deliberately sets to null was
therefore dropped, and the function failed to invoke on the missing argument.

Use exclude_unset instead: keep the arguments the model actually provided (null
included) and omit only the ones it left out, so the function's own defaults still
apply. Because the input model is generated from the function signature, its field
defaults match the signature defaults, so omitted optionals are unchanged.

Fixes microsoft#5934

Signed-off-by: Yufeng He <40085740+he-yufeng@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 14, 2026 11:05
@giles17 giles17 added the python Usage: [Issues, PRs], Target: Python label Jul 14, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a Python tool-invocation edge case where explicitly-provided null arguments were being dropped during argument validation, which can break invocation of required-but-nullable parameters in auto function calling.

Changes:

  • Switch FunctionTool.invoke() argument dumping from exclude_none=True to exclude_unset=True to preserve explicit null values while still omitting truly-omitted fields.
  • Add regression tests to confirm explicit None is preserved for required nullable parameters and omitted optionals still use function defaults.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
python/packages/core/agent_framework/_tools.py Updates FunctionTool.invoke() argument dumping behavior to preserve explicit nulls.
python/packages/core/tests/core/test_tools.py Adds regression tests for explicit-null preservation and omitted-optional default behavior.

Comment on lines +658 to +662
# exclude_unset (not exclude_none): keep arguments the model
# explicitly provided even when their value is null, and drop
# only the ones it left out, so the function's own defaults
# apply. Excluding null instead would strip a required nullable
# parameter the model deliberately set to null, failing the
Comment on lines +154 to +158
async def test_invoke_preserves_explicit_null_argument():
"""A required nullable argument the model sets to null must reach the function.

Regression for #5934: exclude_none dropped the explicit null, so the required
``unit`` went missing and the invocation failed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

python Usage: [Issues, PRs], Target: Python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Python: [Bug]: Auto function calling removes null arguments

3 participants