Skip to content

fix: build function declaration when a param uses a TYPE_CHECKING-only annotation - #6488

Open
NishchayMahor wants to merge 1 commit into
google:mainfrom
NishchayMahor:fix/function-decl-type-checking-annotations
Open

fix: build function declaration when a param uses a TYPE_CHECKING-only annotation#6488
NishchayMahor wants to merge 1 commit into
google:mainfrom
NishchayMahor:fix/function-decl-type-checking-annotations

Conversation

@NishchayMahor

Copy link
Copy Markdown

Summary

A FunctionTool fails to build its declaration when the tool is defined in a module using from __future__ import annotations and its context parameter is typed with an import guarded by if TYPE_CHECKING: — the pattern ADK's own docs recommend for context params:

from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
    from google.adk.tools.tool_context import ToolContext

def my_tool(x: int, tool_context: ToolContext) -> str:
    ...

Building the declaration raises NameError: name 'ToolContext' is not defined at the first LLM request — even though tool_context is excluded from the schema anyway.

Root cause

_get_function_fields (and the return-type path in _build_response_json_schema) call get_type_hints(func), which resolves all annotations at once, including the excluded context parameter. When that annotation is a TYPE_CHECKING-only forward reference, resolution raises NameError — but only TypeError was caught, so it aborts declaration building on the default JSON-schema path.

Not a duplicate of #4754

#4754 / commit 22fc332 fixed find_context_parameter so the context param is correctly identified and excluded. This is a separate crash further down: schema and return-type resolution still resolve the excluded param's annotation. Verified the repro still fails on current main (which already contains 22fc332).

Fix

Catch NameError/AttributeError alongside TypeError in both spots and fall back to the raw per-parameter annotation — logic that already exists directly below but was unreachable. When get_type_hints succeeds (the common case), behavior is unchanged.

Testing

Added test_type_checking_only_context_annotation_builds_declaration to tests/unittests/tools/test_function_tool_with_import_annotations.py, asserting the declaration builds with the real param described and the context param excluded. Fails on main (NameError), passes with the fix.

python -m pytest tests/unittests/tools/test_function_tool_with_import_annotations.py -q
11 passed
python -m pytest tests/unittests/tools/test_build_function_declaration.py <this file> -q
52 passed

(Async suites in test_function_tool.py fail identically with and without this change — they need pytest-asyncio in my env — so no regression from this diff.) pyink + isort clean.

This fix was developed with AI assistance; I found the bug, verified the root cause and the fix end-to-end, and reviewed every line.

@google-cla

google-cla Bot commented Jul 27, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@adk-bot adk-bot added the tools [Component] This issue is related to tools label Jul 27, 2026
@rohityan

Copy link
Copy Markdown
Collaborator

Hi @NishchayMahor , Thank you for your contribution! It appears you haven't yet signed the Contributor License Agreement (CLA). Please visit https://cla.developers.google.com/ to complete the signing process. Once the CLA is signed, we'll be able to proceed with the review of your PR. Thank you!

@rohityan rohityan added the request clarification [Status] The maintainer need clarification or more information from the author label Jul 27, 2026
@NishchayMahor

Copy link
Copy Markdown
Author

Thanks @rohityan — I've signed the CLA at https://cla.developers.google.com/ under nishchaymahor@gmail.com, which is the same email the commit is authored with. The cla/google check still shows the run from when the PR was first opened; could it be re-run when you get a chance? Happy to rebase onto latest main as well since it's showing behind.

…y annotation

When a tool is defined in a module using `from __future__ import annotations`
and its context parameter is typed with an import guarded by
`if TYPE_CHECKING:`, `get_type_hints()` raises NameError while resolving that
(excluded) parameter, aborting declaration building on the default JSON-schema
path. Only TypeError was caught. Catch the unresolvable-forward-reference
errors too and fall back to the raw per-parameter annotation, which already
handles this case. The same guard is applied to return-type resolution.

This is distinct from google#4754 (which fixed find_context_parameter): the context
parameter is now correctly identified and excluded, but schema/return
resolution still resolves its annotation and crashes.
@NishchayMahor
NishchayMahor force-pushed the fix/function-decl-type-checking-annotations branch from 4adbf26 to bc467b9 Compare July 27, 2026 21:05
@NishchayMahor

Copy link
Copy Markdown
Author

Rebased onto latest main (was showing behind) — no conflicts, and the change is unchanged: the two except broadenings in _function_tool_declarations.py plus the regression test. The CLA check is green now too. Ready for review whenever you have a moment, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants