Skip to content

[bug] failover combo can terminate on stale undeclared MCP tool identity instead of trying next target #5407

Closed

Description

@RHODIZSECURITY

Client or integration

Claude Code

Area

Tools / MCP / web search

Summary

A request sent through a failover combo can reach a routed fallback model that emits an MCP tool identity absent from the current request's declared tool catalog. OpenCodex correctly rejects the undeclared tool fail-closed, but the entire combo turn then terminates with a user-visible 502 even when later combo targets remain available.

Expected behavior: keep the undeclared-tool guard fail-closed. Never execute or silently alias an undeclared tool. If the bad tool call occurs before any response output or side effect is committed, classify that target response as incompatible with the current tool catalog and safely continue to the next eligible combo target using the exact same current catalog.

Reproduction

  1. Configure a failover combo with at least two routed targets.
  2. Send a Claude Code / Anthropic-compatible request with an explicit MCP tool catalog.
  3. Include prior/history text containing a tool identity that is absent from the current request catalog.
  4. Let a non-primary fallback model emit that historical/absent tool identity before any output or side effect is committed.
  5. Observe the undeclared-tool guard reject the call, followed by a terminal 502 instead of safe failover to the next target.

This has been intermittent rather than deterministic. A control request with a single currently declared tool succeeds when the model calls only that declared tool.

Related issues/fixes that may overlap but do not appear identical: #5100 (tool-name/namespace normalization) and #5101 (legacy dotted-function replay). This report is specifically about a tool identity that is not present in the current request catalog.

Version

2.55.0 when captured; runtime subsequently upgraded to 2.59.0.

Operating system

Ubuntu Server Linux (x86_64)

Provider and model

OpenRouter / NVIDIA Nemotron routed fallback (captured occurrences)

Logs or error output

routed provider emitted undeclared client tool "mcp__github__github_repo_get";
only request-declared tools may be called

Five captured occurrences in one window used absent/stale GitHub MCP names:

  • mcp__github__list_branches (2)
  • mcp__github__list_pull_requests (1)
  • mcp__github__gh_pr_list (1)
  • mcp__github__github_repo_get (1)

Some names can exist in other GitHub MCP catalogs; the security-relevant invariant is that none was declared by the affected current request.

Screenshots and supporting files

No attachment is required for the reproduction shape above. The local security guard was intentionally left enabled throughout testing.

Redacted configuration

{
  "combo": {
    "strategy": "failover",
    "targets": [
      "provider-a/model-a",
      "openrouter/nvidia-model",
      "provider-c/model-c"
    ]
  },
  "tool_guard": "fail-closed"
}

Checks

  • I searched existing issues and documentation.
  • I removed secrets, tokens, account details, request credentials, and personal data.

Activity

  1. added
    account-poolOAuth, credentials, Codex pool, quota, failover, plans
    toolstool_calls, MCP, web-search / sidecar tools
    on Sep 21, 2026
  2. github-actions commented on Sep 21, 2026

    @github-actions
    Contributor

    Issue reopened

    The report now contains the information required by the automated check. Thanks for updating it.

  3. lidge-jun commented on Sep 23, 2026

    @lidge-jun
    Owner

    Partial progress: #5675 (squash-merged as aed3bb8, carrying #5489) makes combos fail over on undeclared zero-output tool calls on the Responses path. The Claude Code / Anthropic path described here is unchanged, so this stays open.

  4. added
    priority: P1High: reproducible failure in a core path (routing, failover, account pool, streaming, usage, auth,
    on Sep 24, 2026
  5. FredAmartey commented on Sep 24, 2026

    @FredAmartey
    Contributor

    On current dev (ed181a0d0) this no longer ends in a 502 on the Claude Code path. The captured errors are from 2.55.0; since #4799 (2.57.0) the undeclared-tool refusal applies to the Responses protocol only, and Anthropic and Chat requests relay the call, as the compatibility contract in structure/adapters/compatibility-contracts.md states. I checked both target families with a two-target failover combo and a stale first tool call: a bridged target such as OpenRouter over openai-chat relays the call to Claude Code, whose tool runner refuses it, and an openai-responses target has the call refused and the combo fails over to the next target. So what is left is a policy question: whether a combo on the Anthropic wire should hop on an undeclared first tool call instead of relaying it, which would narrow that contract.

  6. lidge-jun commented on Sep 25, 2026

    @lidge-jun
    Owner

    Closing as fixed in v2.65.0. The reported failure, a failover combo ending in a 502 on a stale undeclared MCP tool call, no longer happens on either path:

    One question remains, and it is about policy: should a combo on the Anthropic wire move to the next target on an undeclared first tool call instead of relaying it? That would narrow the contract in structure/adapters/compatibility-contracts.md. If you want that behavior, please open it as a feature proposal. If the 502 comes back on v2.65.0 or later, please reopen with the version and a redacted log.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    account-poolOAuth, credentials, Codex pool, quota, failover, plansbugSomething isn't workingpriority: P1High: reproducible failure in a core path (routing, failover, account pool, streaming, usage, auth,toolstool_calls, MCP, web-search / sidecar tools

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions