OpenAPI parser doesn't let an operation parameter override the path-level one: the model is asked for the same path value twice, and the wrong one is sent
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 86/100
Research direction
Start at OpenApiSpecParser._collect_operations() and run the supplied httpx.MockTransport reproduction to observe the duplicate arguments and request URL. Inspect OperationParser’s parameter handling and the reported PR test, then confirm that an operation-level parameter is used once while same-name parameters in other locations still work.
Written by the indexing model from the issue text.
Description
🔴 Required Information
Describe the Bug:
OpenApiSpecParser._collect_operations() appends path-level parameters to every operation's own parameters without checking for overrides:
operation_dict["parameters"] = operation_dict.get("parameters", []) + path_item.get("parameters", [])
The OpenAPI 3 Path Item Object says an operation-level parameter with the same name and in overrides the path-level one. Declaring the shared path parameter once at the path level and refining it on an operation (a more specific description, pattern or enum) is common. ADK keeps both, OperationParser de-duplicates the names, and the tool then asks the model for the same URL segment twice as two required arguments: account_id and account_id_0. When the model fills both, both map to the same {accountId} placeholder and the path-level value wins, so the operation's own, more specific parameter is silently dropped from the request.
Steps to Reproduce:
pip install google-adk(reproduced onmain@ 3f4bb8fa).- Run the script below: an
OpenAPIToolsetwhose/accounts/{accountId}path declaresaccountIdand whoseGEToverrides it. HTTP goes to anhttpx.MockTransport.
Expected Behavior:
One required argument, account_id, described by the operation-level parameter; {"account_id": "ACC-123"} requests /accounts/ACC-123.
Observed Behavior:
model is asked for: ['account_id', 'account_id_0']
args: {'account_id': 'ACC-123', 'account_id_0': 'ACC-999'} -> request: https://crm.example.com/accounts/ACC-999
Environment Details:
- ADK Library Version (pip show google-adk):
main@ 3f4bb8fa - Desktop OS: Windows 11
- Python Version (python -V): 3.12.10
Model Information:
- Are you using LiteLLM: No
- Which model is being used: N/A (tool declaration and request building)
🟡 Optional Information
Minimal Reproduction Code:
import asyncio
import httpx
from google.adk.tools.openapi_tool.openapi_spec_parser.openapi_toolset import OpenAPIToolset
spec = {
"openapi": "3.0.0",
"info": {"title": "CRM", "version": "1"},
"servers": [{"url": "https://crm.example.com"}],
"paths": {"/accounts/{accountId}": {
"parameters": [{"name": "accountId", "in": "path", "required": True,
"schema": {"type": "string"}, "description": "Shared account id"}],
"get": {
"operationId": "getAccount",
"parameters": [{"name": "accountId", "in": "path", "required": True,
"schema": {"type": "string", "pattern": "^ACC-[0-9]+$"},
"description": "Account id, e.g. ACC-123"}],
"responses": {"200": {"description": "ok"}},
},
}},
}
sent = []
toolset = OpenAPIToolset(
spec_dict=spec,
httpx_client_factory=lambda: httpx.AsyncClient(transport=httpx.MockTransport(
lambda r: sent.append(str(r.url)) or httpx.Response(200, json={}))),
)
async def main():
tool = (await toolset.get_tools())[0]
schema = tool._get_declaration().parameters_json_schema
print("model is asked for:", schema["required"])
args = {"account_id": "ACC-123"}
if "account_id_0" in schema["properties"]:
args["account_id_0"] = "ACC-999" # a model filling both required fields
await tool.run_async(args=args, tool_context=None)
print("args:", args, "-> request:", sent[0])
asyncio.run(main())
Suggested fix: when merging, skip path-level parameters whose (name, in) the operation already declares. Parameters with the same name but a different location are still merged. I have a PR ready with a test.
How often has this issue occurred?:
- Always (100%): any spec that overrides a path-level parameter on an operation.
- Dominant language
- Python
- Stars
- 21.6k
- Forks
- 4k
- Avg merge
- 13h 49m
- Merged PRs (30d)
- 10
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from google/adk-python
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
google/adk-python#7217 · 1 comment ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
google/adk-python#7206 · 1 comment ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
google/adk-python#7196 · 1 comment ·
-
eval request clarification
Difficulty 1/5 1-3 hours Newbie friendliness 86/100
google/adk-python#7146 · 2 comments · 1 assignee ·
-
mcp
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
google/adk-python#7144 · 1 comment · 1 assignee ·
All issues in google/adk-python
Similar issues
-
area/auth bug comp/agent P3 platform/discord type/security
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
NousResearch/hermes-agent#117848 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
bancolombia/sentinel#23 ·
-
test md OpenCI
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
-
integration:quickjs org:external priority:backlog topic:code-interpreter topic:middleware type:feature
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
langchain-ai/deepagents#6450 ·
-
bug client
Difficulty 2/5 1-3 hours Newbie friendliness 88/100