#3776·composio

[Bug]: Tool Router: session.search silently omits no-auth toolkits when the session also enables an auth-based toolkit

Author: jaijunejaCreated Jul 9, 2026Updated Sep 9, 2026
Labelssupport

SDK Language

Python SDK (composio package)

SDK Version

composio==0.15.0

Runtime Environment

Python 3.12 on MacOS

Environment

Production Deployment

Describe the Bug

Summary

In a Tool Router v3.1 session that enables both an auth-based toolkit (e.g. gmail) and a no-auth toolkit (e.g. hackernews), session.search never returns the no-auth toolkit's tools — it is absent from results, tool_schemas, and toolkit_connection_statuses for every query, including a query containing the literal tool slug. session.execute of the no-auth toolkit's tools works fine in the same session, and a session containing only no-auth toolkits searches correctly — so this looks like the search scope/index build excluding no-auth toolkits whenever an auth-based toolkit is present.

Steps to Reproduce

  1. Initialize a tool router session with a no-auth toolkit (e.g. hackernews) and an auth-based toolkit (e.g. gmail)
  2. Run a tool search for one of the tools in the no-auth toolkit
  3. Notice that no relevant results are returned

Minimal Reproducible Example

bash
`composio_client` 1.43.0 (also 1.39.0), Python 3.x:


import composio_client

client = composio_client.Composio(api_key="...")

# Case 1 — no-auth toolkit alone: search works.
s1 = client.tool_router.session.create(
    user_id="repro_user",
    toolkits={"enable": ["hackernews"]},
)
r1 = client.tool_router.session.search(
    s1.session_id,
    queries=[{"use_case": "get top stories from the hacker news front page"}],
)
# r1.results[0].primary_tool_slugs -> HACKERNEWS_GET_TOP_STORIES, ...  ✅

# Case 2 — same toolkit + any auth-based toolkit: hackernews vanishes.
s2 = client.tool_router.session.create(
    user_id="repro_user",
    toolkits={"enable": ["gmail", "hackernews"]},
)
r2 = client.tool_router.session.search(
    s2.session_id,
    queries=[{"use_case": "get top stories from the hacker news front page"}],
)
# r2.results[0].primary_tool_slugs -> GMAIL_FETCH_EMAILS, ...          ❌
# r2.toolkit_connection_statuses   -> gmail only; hackernews absent    ❌

# Execute of the "invisible" toolkit works in the same session:
e2 = client.tool_router.session.execute(
    s2.session_id,
    tool_slug="HACKERNEWS_GET_TOP_STORIES",
    arguments={},
)
# e2.data -> {"count": 500, "story_ids": [...]}                        ✅

Error Output / Stack Trace

bash
n/a - this is a behavioural error rather than an exception being raised.

Reproducibility

  • Always reproducible
  • Intermittent / Sometimes
  • Happened once, can’t reproduce

Additional Context or Screenshots

What we ruled out

  • Explicit tool allowlist: adding tools={"hackernews": {"enable": [<all 14 slugs>]}} to session.create does not change search behaviour.
  • Connected-account pinning: pinning or omitting accounts for the authed toolkit makes no difference.
  • Connection status: an unconnected auth-based toolkit (fresh user_id, no connected accounts at all) is still searchable, so search is not gated on active connections — only no-auth toolkits are dropped.
  • Which authed toolkit: reproduced with gmail, googlesheets, github, shopify as the co-enabled toolkit.
  • Which no-auth toolkit: reproduced with hackernews and composio.
  • Query phrasing: a query consisting of the literal slug HACKERNEWS_GET_TOP_STORIES still returns only Gmail tools.
  • SDK version: identical on 1.39.0 and 1.43.0.

Two no-auth toolkits together (hackernews + composio, no authed toolkit) search fine — the trigger is specifically mixing no-auth with auth-based.

Expected

No-auth toolkits enabled in a session should participate in session.search regardless of what else the session enables — same as they do in a single-kind session, and consistent with session.execute accepting their tools.

Impact

Agents with both connected apps and no-auth apps cannot discover the no-auth apps' tools via search (the LLM is told to search before executing), so those toolkits are effectively unusable in mixed sessions without client-side workarounds. Our current workaround injects the no-auth toolkits' tools via experimental.custom_toolkits on every search request and rewrites the LOCAL_* slugs back — happy to share details, but we'd love to delete it.

Aside observed while building the workaround: experimental.custom_toolkits entries always contribute ~5 results per query even when completely irrelevant (real toolkits are correctly flushed to zero; customs never are). A relevance threshold for customs would make that feature much more useful.