Repository navigation
[bug] failover combo can terminate on stale undeclared MCP tool identity instead of trying next target #5407
Description
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
- Configure a failover combo with at least two routed targets.
- Send a Claude Code / Anthropic-compatible request with an explicit MCP tool catalog.
- Include prior/history text containing a tool identity that is absent from the current request catalog.
- Let a non-primary fallback model emit that historical/absent tool identity before any output or side effect is committed.
- 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 calledFive 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
github-actions commentedon Sep 21, 2026
Issue reopened
The report now contains the information required by the automated check. Thanks for updating it.
fix(combo): fail over undeclared zero-output tools
fix(responses): bundle lane E — combo resend safety, WebSocket replac…
lidge-jun commentedon Sep 23, 2026
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.
FredAmartey commentedon Sep 24, 2026
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 instructure/adapters/compatibility-contracts.mdstates. I checked both target families with a two-target failover combo and a stale first tool call: a bridged target such as OpenRouter overopenai-chatrelays the call to Claude Code, whose tool runner refuses it, and anopenai-responsestarget 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.lidge-jun commentedon Sep 25, 2026
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:
devwith a two-target combo.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.