Bug
When a request from Claude Code (Anthropic Messages API format) includes an Anthropic server tool like web_search, Manifest's toChatTools adapter converts it to chat completions format but strips parameters because it's a server tool. The tool is then forwarded to a third-party provider (e.g. MiniMax) that requires parameters on every function tool, resulting in a 400.
Reproduction
Request from Claude Code → Manifest gateway (self-hosted) → MiniMax (MiniMax-M2.7-highspeed), chat completions.
The inbound tool (Anthropic Messages format):
{ "type": "web_search_20250305", "name": "web_search" }
The outbound tool after toChatTools (chat completions format):
{ "type": "function", "function": { "name": "web_search" } }
MiniMax response:
invalid params, function parameters is empty (2013)
Phoenix issue: 99ce618b-8c80-47d0-919d-cd5ac9d994d9 (no_fix_found)
Root cause
packages/backend/src/routing/proxy/anthropic-messages-adapter.ts, toChatTools:
...(tool.input_schema !== undefined
? { parameters: normalizeOpenAiFunctionSchema(tool.input_schema) }
: typeof tool.type === 'string' &&
tool.type !== 'custom' &&
!isAnthropicServerToolType(tool.type)
? { parameters: DEFAULT_CUSTOM_TOOL_INPUT_SCHEMA }
: {}),
Anthropic server tools (web_search_, bash_, computer_, text_editor_, etc.) match isAnthropicServerToolType, so the else branch is empty — no parameters is added. The tool is then forwarded to the provider as { type: "function", function: { name: "web_search" } }, which MiniMax (and likely other strict providers) reject.
Fix options
-
Inject DEFAULT_CUSTOM_TOOL_INPUT_SCHEMA for server tools too when converting to chat completions format — so the outbound tool always has parameters. Safe because the provider ignores the schema for a tool it doesn't recognize; the error is the missing field, not the schema content.
-
Drop Anthropic server tools entirely when routing to a non-Anthropic provider — they're Anthropic-internal tools that a third-party provider can't execute anyway. The model would then get no tool and respond without web search, rather than the request failing.
Option 2 is more correct (the tool can't work on MiniMax regardless), but option 1 is the smaller change and unblocks the request. Probably both: drop server tools for non-Anthropic providers, and as a belt-and-suspenders default, always emit parameters on any function tool.
Bug
When a request from Claude Code (Anthropic Messages API format) includes an Anthropic server tool like
web_search, Manifest'stoChatToolsadapter converts it to chat completions format but stripsparametersbecause it's a server tool. The tool is then forwarded to a third-party provider (e.g. MiniMax) that requiresparameterson every function tool, resulting in a 400.Reproduction
Request from Claude Code → Manifest gateway (self-hosted) → MiniMax (
MiniMax-M2.7-highspeed), chat completions.The inbound tool (Anthropic Messages format):
{ "type": "web_search_20250305", "name": "web_search" }The outbound tool after
toChatTools(chat completions format):{ "type": "function", "function": { "name": "web_search" } }MiniMax response:
Phoenix issue:
99ce618b-8c80-47d0-919d-cd5ac9d994d9(no_fix_found)Root cause
packages/backend/src/routing/proxy/anthropic-messages-adapter.ts,toChatTools:Anthropic server tools (
web_search_,bash_,computer_,text_editor_, etc.) matchisAnthropicServerToolType, so theelsebranch is empty — noparametersis added. The tool is then forwarded to the provider as{ type: "function", function: { name: "web_search" } }, which MiniMax (and likely other strict providers) reject.Fix options
Inject
DEFAULT_CUSTOM_TOOL_INPUT_SCHEMAfor server tools too when converting to chat completions format — so the outbound tool always hasparameters. Safe because the provider ignores the schema for a tool it doesn't recognize; the error is the missing field, not the schema content.Drop Anthropic server tools entirely when routing to a non-Anthropic provider — they're Anthropic-internal tools that a third-party provider can't execute anyway. The model would then get no tool and respond without web search, rather than the request failing.
Option 2 is more correct (the tool can't work on MiniMax regardless), but option 1 is the smaller change and unblocks the request. Probably both: drop server tools for non-Anthropic providers, and as a belt-and-suspenders default, always emit
parameterson any function tool.