Summary
POST /provider/v1/responses returns HTTP 400 {"error":{"message":"Invalid input","type":"invalid_request_error","param":"input"}} for any request whose input array contains a tool_search_call or tool_search_output item.
Codex emits these items natively on the Responses wire (wire_api = "responses"), so every turn in which the model performs a tool search is killed before the model runs, and the task ends as a system error. On deepseek/deepseek-v4.1-flash this makes every MCP / plugin tool unusable: Codex defers MCP tools (js, js_reset, ...) behind a tool search, so the first time the agent reaches for Chrome or Computer Use the conversation history gains a tool_search_call/tool_search_output pair and the next request 400s.
Expected Behavior
The endpoint should accept tool_search_call / tool_search_output input items, or at minimum accept the request and ignore them. They are client-executed history items, the same class as function_call / function_call_output, which the endpoint already accepts today.
Actual Behavior
The whole request is rejected with 400 before any model output. Body is 84 bytes:
{"error":{"message":"Invalid input","type":"invalid_request_error","param":"input"}}
Steps to reproduce the issue
Baseline (200 OK):
curl -sS https://api.commandcode.ai/provider/v1/responses \
-H "Authorization: Bearer $CMDCODE_KEY" \
-H 'content-type: application/json' \
-d '{
"model": "deepseek/deepseek-v4.1-flash",
"stream": false,
"max_output_tokens": 16,
"input": [{"role":"user","content":[{"type":"input_text","text":"hi"}]}]
}'
Now append one tool_search_call item to input:
"input": [
{"role":"user","content":[{"type":"input_text","text":"hi"}]},
{"type":"tool_search_call","call_id":"call_x1","status":"completed","execution":"client","arguments":{"query":"cua"}}
]
Result: HTTP 400, the 84-byte body above.
Same with tool_search_output:
{"type":"tool_search_output","call_id":"call_x1","status":"completed","execution":"client","tools":[]}
Result: HTTP 400, same body.
Matrix measured against https://api.commandcode.ai/provider/v1/responses with model deepseek/deepseek-v4.1-flash:
input contents |
result |
| plain user message |
200 |
+ tool_search_call (full fields) |
400 |
+ tool_search_call, minimal fields (type/call_id/arguments), no tools array on the request |
400 |
+ tool_search_call, arguments as a JSON string instead of an object |
400 |
+ tool_search_output, tools: [] |
400 |
+ tool_search_output, one real function tool in tools |
400 |
+ function_call and function_call_output |
200 |
The trigger is the item type itself, not a missing or extra field.
Real-world impact (Codex Desktop 0.155.0-alpha.9.2, macOS, zsh)
Turn 01a0bcca-9210-7650-bc44-862ddf3a9baf:
- The user asks the agent to drive Chrome. The agent's
js / js_reset calls start coming back as unsupported call: js (the mcp__cua_repl namespace is missing from the emitted calls).
- The model then issues one tool search (
arguments: {"query": "cua_repl javascript execution browser control"}) and Codex writes a tool_search_call + tool_search_output pair into the conversation history.
- The next request 400s and the turn ends as:
{"type":"task_complete","error":{"message":"{\"error\":{\"message\":\"Invalid input\",\"type\":\"invalid_request_error\",\"param\":\"input\"}}","codex_error_info":"other"}}
A parallel thread on the same provider that never triggered a tool search ran to completion, matching the repro above.
Command Code Version
Provider API (gateway), server-side. Client: Codex Desktop 0.155.0-alpha.9.2, wire_api = "responses", base_url = https://api.commandcode.ai/provider/v1, model deepseek/deepseek-v4.1-flash.
Operating System
macOS
Terminal/IDE
Codex Desktop
Shell
zsh
Session file (optional)
No response
Fix prompt (optional)
POST /provider/v1/responses in the Provider API gateway rejects any request whose input array contains a tool_search_call or tool_search_output item, returning 400 {"error":{"message":"Invalid input","param":"input"}}. The endpoint already accepts function_call / function_call_output items, so extend the same history-item handling to tool_search_call / tool_search_output: parse them as client-executed history items and either carry them through the upstream translation or drop them, instead of failing request validation.
Reproduce: POST a request with a plain user message -> 200; append one tool_search_call item -> 400. Exact bodies are in the issue.
Check: both item types return a normal completion, and a Codex turn that performs a tool search no longer dies with param: "input".
Additional context
Summary
POST /provider/v1/responsesreturns HTTP 400{"error":{"message":"Invalid input","type":"invalid_request_error","param":"input"}}for any request whoseinputarray contains atool_search_callortool_search_outputitem.Codex emits these items natively on the Responses wire (
wire_api = "responses"), so every turn in which the model performs a tool search is killed before the model runs, and the task ends as a system error. Ondeepseek/deepseek-v4.1-flashthis makes every MCP / plugin tool unusable: Codex defers MCP tools (js,js_reset, ...) behind a tool search, so the first time the agent reaches for Chrome or Computer Use the conversation history gains atool_search_call/tool_search_outputpair and the next request 400s.Expected Behavior
The endpoint should accept
tool_search_call/tool_search_outputinput items, or at minimum accept the request and ignore them. They are client-executed history items, the same class asfunction_call/function_call_output, which the endpoint already accepts today.Actual Behavior
The whole request is rejected with 400 before any model output. Body is 84 bytes:
{"error":{"message":"Invalid input","type":"invalid_request_error","param":"input"}}Steps to reproduce the issue
Baseline (200 OK):
Now append one
tool_search_callitem toinput:Result: HTTP 400, the 84-byte body above.
Same with
tool_search_output:{"type":"tool_search_output","call_id":"call_x1","status":"completed","execution":"client","tools":[]}Result: HTTP 400, same body.
Matrix measured against
https://api.commandcode.ai/provider/v1/responseswith modeldeepseek/deepseek-v4.1-flash:inputcontentstool_search_call(full fields)tool_search_call, minimal fields (type/call_id/arguments), notoolsarray on the requesttool_search_call,argumentsas a JSON string instead of an objecttool_search_output,tools: []tool_search_output, one realfunctiontool intoolsfunction_callandfunction_call_outputThe trigger is the item
typeitself, not a missing or extra field.Real-world impact (Codex Desktop 0.155.0-alpha.9.2, macOS, zsh)
Turn
01a0bcca-9210-7650-bc44-862ddf3a9baf:js/js_resetcalls start coming back asunsupported call: js(themcp__cua_replnamespace is missing from the emitted calls).arguments: {"query": "cua_repl javascript execution browser control"}) and Codex writes atool_search_call+tool_search_outputpair into the conversation history.{"type":"task_complete","error":{"message":"{\"error\":{\"message\":\"Invalid input\",\"type\":\"invalid_request_error\",\"param\":\"input\"}}","codex_error_info":"other"}}A parallel thread on the same provider that never triggered a tool search ran to completion, matching the repro above.
Command Code Version
Provider API (gateway), server-side. Client: Codex Desktop 0.155.0-alpha.9.2,
wire_api = "responses",base_url = https://api.commandcode.ai/provider/v1, modeldeepseek/deepseek-v4.1-flash.Operating System
macOS
Terminal/IDE
Codex Desktop
Shell
zsh
Session file (optional)
No response
Fix prompt (optional)
POST /provider/v1/responsesin the Provider API gateway rejects any request whoseinputarray contains atool_search_callortool_search_outputitem, returning 400{"error":{"message":"Invalid input","param":"input"}}. The endpoint already acceptsfunction_call/function_call_outputitems, so extend the same history-item handling totool_search_call/tool_search_output: parse them as client-executed history items and either carry them through the upstream translation or drop them, instead of failing request validation.Reproduce: POST a request with a plain user message -> 200; append one
tool_search_callitem -> 400. Exact bodies are in the issue.Check: both item types return a normal completion, and a Codex turn that performs a tool search no longer dies with
param: "input".Additional context
/v1/responsesrejects Codex's non-function tool types (tools.N.type) and breaks the endpoint for Codex #885 (tools.N.typeon/v1/responses), Provider API rejects tool_search function calls from Codex clients with 400 "Missing required parameter: 'input[N].arguments'" #745 (tool_searchinvocation on/chat/completions), Provider API: add OpenAI Responses API support (POST /provider/v1/responses) #832 (Responses support). This is a follow-up on the same endpoint: thetoolsarray is accepted now, but theinputhistory items still are not.tool_search_output.tools[]can itself contain{"type":"namespace","name":"mcp__node_repl", ...}entries with nestedfunctiontools, so whatever translation is added may need to tolerate nested namespace entries as well.