Skip to content

fix(tools): send the body for oneOf/anyOf/allOf OpenAPI request schemas - #6992

Open
chelsealong wants to merge 1 commit into
google:mainfrom
chelsealong:fix-6991-oneof-body-silently-dropped
Open

fix(tools): send the body for oneOf/anyOf/allOf OpenAPI request schemas#6992
chelsealong wants to merge 1 commit into
google:mainfrom
chelsealong:fix-6991-oneof-body-silently-dropped

Conversation

@chelsealong

Copy link
Copy Markdown
Contributor

Fixes #6991

Problem

For an OpenAPI operation whose request body schema is polymorphic (oneOf,
anyOf, allOf) or has no type, RestApiTool builds a correct function
declaration with a body parameter, the model supplies that argument — and
the HTTP request is sent with no body at all. No exception, no warning,
no log line; Content-Type: application/json is still set, so the server
receives a well-formed request with Content-Length: 0.

Root cause

OperationParser._process_request_body names a polymorphic/untyped body
parameter 'body' (instead of '') specifically to avoid emitting an
empty-named property in the function declaration (this was the fix for
#2213). RestApiTool._prepare_request_params, however, only recognized the
legacy '' sentinel when deciding which parameter represents the full body:

if param.param_location == "body" and not param.original_name:

Since a polymorphic/untyped schema's parameter is named 'body', not '',
this condition never matches, body_data stays None, and json is never
set on the outgoing request — silently.

Fix

_prepare_request_params now treats both '' and 'body' as the full-body
sentinel, matching what OperationParser actually emits:

if param.param_location == "body" and param.original_name in ("", "body"):

Test plan

Added test_prepare_request_params_oneof_body, which builds a oneOf
request body schema (mirroring the issue's {card}/{iban} example) and
asserts the constructed request actually carries the JSON body.

Confirmed the new test fails without the fix (git checkout HEAD~1 -- src/google/adk/tools/openapi_tool/openapi_spec_parser/rest_api_tool.py):

FAILED tests/unittests/tools/openapi_tool/openapi_spec_parser/test_rest_api_tool.py::TestRestApiTool::test_prepare_request_params_oneof_body - KeyError: 'json'
1 failed, 63 deselected in 1.84s

And passes with the fix restored:

$ python3 -m pytest tests/unittests/tools/openapi_tool/openapi_spec_parser/test_rest_api_tool.py -q
64 passed, 17 warnings in 1.75s

Full openapi_tool suite and the broader tools suite also pass:

$ python3 -m pytest tests/unittests/tools/openapi_tool/ -q
280 passed, 24 warnings in 3.64s

$ python3 -m pytest tests/unittests/tools/ -q
2126 passed, 1 skipped, 762 warnings in 40.31s

Formatting/lint checked with the repo's configured tools:

$ python3 -m pyink --config pyproject.toml --check src/google/adk/tools/openapi_tool/openapi_spec_parser/rest_api_tool.py tests/unittests/tools/openapi_tool/openapi_spec_parser/test_rest_api_tool.py
All done! 2 files would be left unchanged.

$ python3 -m isort --settings-path pyproject.toml --check src/google/adk/tools/openapi_tool/openapi_spec_parser/rest_api_tool.py tests/unittests/tools/openapi_tool/openapi_spec_parser/test_rest_api_tool.py
(no changes)

$ python3 -m ruff check --config pyproject.toml src/google/adk/tools/openapi_tool/openapi_spec_parser/rest_api_tool.py
All checks passed!

Disclosure

This PR was prepared with the assistance of an AI coding agent (Claude),
under human review before submission.

OperationParser names a polymorphic or untyped request body parameter
'body' (instead of '' used for plain scalar bodies) to avoid emitting
an empty-named property in the function declaration. RestApiTool's
_prepare_request_params only recognized the '' sentinel, so it never
matched the 'body'-named parameter and silently sent no body at all.

Fixes google#6991
@chelsealong
chelsealong force-pushed the fix-6991-oneof-body-silently-dropped branch from 45c873e to 5d203a1 Compare September 3, 2026 00:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RestApiTool silently sends an empty request body when the OpenAPI schema uses oneOf/anyOf/allOf

2 participants