Skip to content

fix: extract URL fragment key=value pairs as query params in _prepare_request_params#4800

Open
saiprasanth-git wants to merge 5 commits intogoogle:mainfrom
saiprasanth-git:main
Open

fix: extract URL fragment key=value pairs as query params in _prepare_request_params#4800
saiprasanth-git wants to merge 5 commits intogoogle:mainfrom
saiprasanth-git:main

Conversation

@saiprasanth-git
Copy link

Closes #4598

What's the problem?

When _prepare_request_params builds the final request URL, it uses urlparse to split the URL into its components. The existing code was already smart enough to pull any key=value pairs out of the query string and move them into query_params (so httpx doesn't lose them when it sets the params arg). But it was completely ignoring the fragment part of the URL.

This matters because ApplicationIntegrationToolset sometimes generates endpoint URLs like:

https://integrations.googleapis.com/v2/.../execute?triggerId=api_trigger/Foo#httpMethod=POST

The fragment (httpMethod=POST) was being silently dropped, which caused the downstream API to return HTTP 400.

What changed?

Instead of only looping over parsed_url.query, I refactored the extraction into a single loop that processes both parsed_url.query and parsed_url.fragment:

if parsed_url.query or parsed_url.fragment:
    # Extract parameters from query and fragment
    for part in (parsed_url.query, parsed_url.fragment):
        if part:
            for key, values in parse_qs(part).items():
                query_params.setdefault(
                    key,
                    values[0] if len(values) == 1 else values
                )
    # Rebuild URL without query and fragment
    url = urlunparse(parsed_url._replace(query="", fragment=""))

Using setdefault makes sure any explicitly passed query params always take priority over whatever was embedded in the URL.

Testing

Added test_prepare_request_params_fragment_params_become_query_params which uses a realistic Google Cloud integration URL containing both a query string param and a fragment param. Verifies both end up in query_params and the final URL has no leftover ? or #.

Fixes google#4598: When a URL contains a fragment component (e.g., #triggerId=abc123),
the fragment was being silently dropped. This caused HTTP 400 errors when APIs
expect fragment-encoded parameters to be passed as query string parameters.

This change parses the URL fragment using parse_qs and merges the extracted
key-value pairs into query_params (using setdefault to avoid overriding
explicitly-passed values), consistent with how URL query strings are handled.
…params

Adds test_prepare_request_params_extracts_fragment_key_value_pairs to
verify that URL fragments containing key=value pairs (e.g. #action=POST)
are correctly parsed and added to query_params, alongside query string
params. Regression test for issue google#4598.
Refactor query parameter extraction to handle both query and fragment in a single loop.
Added a test using a realistic Google Cloud integration URL that has both a query string param (triggerId) and a fragment param (httpMethod). Confirms both get moved into query_params and the final URL is clean.
@google-cla
Copy link

google-cla bot commented Mar 12, 2026

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.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses a critical bug where URL fragment parameters were being ignored during request preparation, causing API requests to fail. The change enhances the parameter extraction logic to correctly process key-value pairs found in both the query string and the fragment of a URL, ensuring robust handling of complex endpoint URLs and preventing data loss. This improvement makes the system more resilient to varying URL structures, particularly those generated by tools like ApplicationIntegrationToolset.

Highlights

  • Bug Fix: URL Fragment Parameters: Resolved an issue where key-value pairs embedded in the URL fragment (e.g., #httpMethod=POST) were silently dropped by _prepare_request_params, leading to HTTP 400 errors in downstream API calls, particularly with ApplicationIntegrationToolset.
  • Enhanced Parameter Extraction: Modified the _prepare_request_params function to now correctly parse and extract parameters from both the URL's query string and its fragment component, ensuring all relevant parameters are included in the request.
  • New Test Coverage: Introduced a new unit test, test_prepare_request_params_fragment_params_become_query_params, to specifically validate that parameters from both query and fragment parts of a URL are correctly processed and that the final URL is clean of these components.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • src/google/adk/tools/openapi_tool/openapi_spec_parser/rest_api_tool.py
    • Modified _prepare_request_params to iterate over both parsed_url.query and parsed_url.fragment to extract parameters.
    • Ensured query_params.setdefault is used to prioritize explicitly passed query parameters.
  • tests/unittests/tools/openapi_tool/openapi_spec_parser/test_rest_api_tool.py
    • Added test_prepare_request_params_fragment_params_become_query_params to verify fragment parameter extraction.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@adk-bot adk-bot added the tools [Component] This issue is related to tools label Mar 12, 2026
@adk-bot
Copy link
Collaborator

adk-bot commented Mar 12, 2026

Response from ADK Triaging Agent

Hello @saiprasanth-git, thank you for creating this PR!

Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

You can visit https://cla.developers.google.com/ to see your current agreements or to sign a new one.

This information will help reviewers to review your PR more efficiently. Thanks!

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request fixes a bug in the _prepare_request_params function where URL parameters embedded in the fragment part of a URL were being silently dropped, leading to API errors. The change modifies the function to correctly parse and extract parameters from both the query string and the URL fragment, adding them to the request's query parameters. A new unit test has been added to validate this behavior, ensuring fragment parameters are processed correctly and the final URL is cleaned of both query and fragment components.

@saiprasanth-git
Copy link
Author

@googlebot I signed it

@saiprasanth-git
Copy link
Author

@googlebot check

@saiprasanth-git
Copy link
Author

@googlebot I signed the CLA. Please re-verify.

@rohityan rohityan self-assigned this Mar 12, 2026
@rohityan
Copy link
Collaborator

Hi @saiprasanth-git , Thank you for your contribution! We appreciate you taking the time to submit this pull request.
Can you please fix the failing unit tests, mypy-diff tests and formatting errors.

@rohityan rohityan added the request clarification [Status] The maintainer need clarification or more information from the author label Mar 12, 2026
Remove unnecessary check for query and fragment in URL parsing.
@saiprasanth-git
Copy link
Author

Hi @rohityan, I've addressed the feedback:

  1. Syntax error fixed — removed the redundant outer if parsed_url.query or parsed_url.fragment: guard that had no indented body, which was causing the mypy syntax error on line 384.

Could you please approve the workflow runs so the remaining checks (pyink, unit tests, mypy-diff) can run? Thank you!

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.

ApplicationIntegrationToolset ExecuteConnection requests return HTTP 400 (triggerId fragment not sent)

3 participants