Skip to content

ApplicationIntegrationToolset silently builds no tools when a Connectors schema operation fails, and waits forever on one that never finishes #7165

Closed

Description

@1aifanatic

🔴 Required Information

Describe the Bug:

ConnectionsClient._poll_operation() (used by ApplicationIntegrationToolset for connection entities and actions) has two problems:

  1. A failed operation is treated as success. A finished Connectors long-running operation carries either response or error (google.longrunning.Operation). The loop only checks done, and the callers then read response.jsonSchema / response.operations, falling back to {} / []. So when the lookup fails, for example because of a mistyped entity or action name or a missing permission on the connection, the toolset builds without error and with no tools for that entity. With explicit operations it builds tools against an empty schema, and a failed action produces a tool with an empty display name. Nothing tells the developer why the agent can't reach the connector.
  2. The wait is unbounded. while not operation_done: has no deadline, so an operation that never finishes blocks toolset construction, and therefore agent startup, forever. bf4143a bounded each HTTP call in this client for exactly this reason ("an unavailable endpoint could block agent execution indefinitely"), but the polling loop around those calls is still open-ended.

It also sleeps one extra second after the operation is already done, which slows every entity and action lookup.

Steps to Reproduce:

  1. pip install google-adk (reproduced on main @ f33d492 / 2.9.0).
  2. Run the script below. It builds a real ApplicationIntegrationToolset for a connection whose getEntityType operation finishes with error (entity Acount does not exist). HTTP is stubbed, so no GCP project is needed.

Expected Behavior:
Toolset construction fails with the operation's error message, and a stuck operation fails after a bounded wait.

Observed Behavior:

toolset built; tools: []
elapsed: 1.0s

Environment Details:

  • ADK Library Version (pip show google-adk): 2.9.0 (main @ f33d492)
  • 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 (toolset construction, no model call)

🟡 Optional Information

Minimal Reproduction Code:

import asyncio
from unittest import mock

from google.adk.tools.application_integration_tool import ApplicationIntegrationToolset
from google.adk.tools.application_integration_tool.clients.connections_client import ConnectionsClient

FAILED_OP = {
    "name": "operations/op-1",
    "done": True,
    "error": {"code": 5, "message": "Entity type 'Acount' not found."},
}


def fake_get(url, headers=None, timeout=None):
  resp = mock.MagicMock(status_code=200)
  if url.endswith("?view=BASIC"):
    resp.json.return_value = {"name": "projects/p/locations/us-central1/connections/sfdc",
                              "serviceDirectory": "sd", "host": ""}
  elif "getEntityType" in url:
    resp.json.return_value = {"name": "operations/op-1"}
  else:
    resp.json.return_value = FAILED_OP
  return resp


mod = "google.adk.tools.application_integration_tool.clients.connections_client"
with mock.patch(f"{mod}._mtls_utils.get_api_endpoint", return_value="connectors.googleapis.com"), \
     mock.patch.object(ConnectionsClient, "_get_access_token", return_value="token"), \
     mock.patch(f"{mod}.requests.get", side_effect=fake_get):
  toolset = ApplicationIntegrationToolset(
      project="p", location="us-central1", connection="sfdc",
      entity_operations={"Acount": []},  # typo for "Account"
  )
  print("toolset built; tools:", [t.name for t in asyncio.run(toolset.get_tools())])

Suggested fix: in _poll_operation, raise ValueError with the operation's error message when a finished operation carries error. That's the error type the callers already document. Stop polling after a deadline with TimeoutError, and don't sleep once done is set. I have a PR ready with tests.

How often has this issue occurred?:

  • Always (100%): any failed entity or action schema lookup.

Activity

  1. sanketpatil06 commented on Sep 18, 2026

    @sanketpatil06

    Hi @1aifanatic,
    You've accurately identified the critical issues in ConnectionsClient._poll_operation(): the silent failure to propagate errors from Connectors long-running operations and the unbounded polling loop without a timeout.

    Thank you for the detailed analysis and for opening #7167. Team is reviewing reviewing the PR and test coverage.

  2. 1aifanatic commented on Sep 18, 2026

    @1aifanatic
    ContributorAuthor

    Thank you @sanketpatil06! Glad the analysis and reproduction were helpful. Please let me know if any refinements are needed on the test coverage or timeout semantics as the team reviews #7167.

  3. added a commit that references this issue on Sep 19, 2026
    933f898
  4. 1aifanatic commented on Sep 22, 2026

    @1aifanatic
    ContributorAuthor

    For reviewers, a summary of how #7167 fixes this. Three changes in ConnectionsClient._poll_operation():

    1. Fail loud on schema errors. A finished google.longrunning operation carries either response or error, and the loop only checked done. The callers then read response.jsonSchema / response.operations with {} / [] fallbacks, which is what turned a failed lookup into an empty toolset. A finished operation carrying error now raises ValueError("Operation <id> failed: <message>"), with the message the service returned. ValueError is what get_entity_schema_and_operations() and get_action_schema() already document, and it surfaces from ApplicationIntegrationToolset(...) construction, so a bad entity or a missing permission on the connection shows up at startup instead of as a silently tool-less agent.
    2. Bound the wait. while not operation_done: had no deadline. It now stops after _DEFAULT_OPERATION_TIMEOUT_SECONDS (300 s) with a TimeoutError. Worth noting the individual HTTP calls in this client were already bounded at 30 s by bf4143a; it was only the loop around them that was open-ended, so a stuck operation still blocked agent startup forever.
    3. No more one-second sleep after the operation is already done, which also speeds up every entity and action lookup.

    End to end, with getEntityType finishing as {"done": true, "error": {"code": 5, "message": "Entity type 'Acount' not found."}}:

    before: toolset built; tools: []                                                    (1.0s)
    after:  ValueError - Operation operations/op-1 failed: Entity type 'Acount' not found.  (0.0s)
    

    Tests cover all three: a failed operation raises with the server's message, a never-finishing one raises TimeoutError once the deadline passes (with time mocked), and no sleep happens once done is set. The repro script in the issue body needs no GCP project.

    One thing the PR deliberately does not change: 300 s is a guess at a safe ceiling for slow schema refreshes on large connectors. If the service team has a better number, I'm happy to change it.

  5. adk-bot commented on Sep 24, 2026

    @adk-bot
    Collaborator

    🚨 Automated Spam Detection Alert 🚨
    @maintainers, a suspected spam comment was detected in this thread.

    Reason:

    @samvallad33 posted promotional content for a 3rd party app called 'Vestige' which is unrelated to the repository and issue.
    
  6. added
    spam[Status] Issues suspected of having comments which are spam
    on Sep 24, 2026
  7. 1aifanatic commented on Sep 27, 2026

    @1aifanatic
    ContributorAuthor

    @sanketpatil06 small housekeeping request: the spam label here came from the automated alert above about a third-party comment, which has since been deleted. The report itself isn't spam; you confirmed it on Sept 18, and #7167 is the fix. Could you remove the label so it doesn't affect triage of the issue or the PR? Thanks!

  8. removed
    spam[Status] Issues suspected of having comments which are spam
    on Sep 28, 2026
  9. self-assigned this
    on Oct 29, 2026
  10. added
    wip[Status] This issue is being worked on. Either there is a pending PR or is planned to be fixed
    on Oct 29, 2026
  11. willie3838 commented on Oct 29, 2026

    @willie3838

    Hey @1aifanatic thanks for contributing to this issue, we appreciate it. An internal team will be taking this over and credit your work!

  12. added a commit that references this issue on Nov 10, 2026
    ab63844
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

tools[Component] This issue is related to toolswip[Status] This issue is being worked on. Either there is a pending PR or is planned to be fixed

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions