Client or integration
Codex App (Windows desktop)
Area
Tools / Responses continuation / provider compatibility
Summary
deepseek/deepseek-v4-flash on the native openai-responses route returns HTTP 400 when Codex sends a continuation whose input history contains a developer message between a function_call and its matching function_call_output.
The tool itself executes successfully, the function_call_output is present, and the call_id matches exactly. The failure is structural/interleaving-related:
function_call(call_id=X)
→ message(role=developer, content=...)
→ function_call_output(call_id=X, output=successful tool result)
Upstream error:
No tool output found for tool call X.
This is reproducible and reversible in one workspace. The developer message content is sourced verbatim from a local task_plan.md context file. Temporarily renaming that file makes the same DeepSeek tool call succeed; restoring it makes the 400 return immediately.
Important nuance: the exact Codex-side mechanism that injects this developer message is not yet identified. We initially suspected a planning-with-files PostToolUse hook, but static inspection ruled that out as the direct source: that hook only emits a short fixed reminder and does not read task_plan.md. The failing request nevertheless contains a developer message matching the beginning of task_plan.md verbatim.
Reproduction
Environment A (failing workspace):
- Open a Codex workspace that contains a non-empty
task_plan.md and where the current Codex context-injection setup causes part of that file to appear as a developer message in Responses history.
- Select
deepseek/deepseek-v4-flash with Max effort.
- Start a fresh conversation.
- Trigger exactly one shell tool call, for example:
Get-Content -Path "D:\AI\storycard\README.md" -TotalCount 5
- The first DeepSeek Responses request returns HTTP 200 and emits the tool call.
- Codex executes the command successfully.
- The follow-up
/v1/responses request is sent, but the relevant input order is:
function_call(call_id=X)
message(role=developer, text copied from task_plan.md)
function_call_output(call_id=X, output="Exit code: 0 ...")
- DeepSeek returns HTTP 400:
No tool output found for tool call X.
A/B/ABA validation on the same workspace:
task_plan.md present: failure reproduced deterministically (5/5 observed failures in prior sessions).
- Rename only
task_plan.md → task_plan.md.disabled, leaving progress.md, findings.md, AGENTS.md, hooks, model, workspace and OpenCodex unchanged: the same single-tool DeepSeek test succeeds.
- Restore the exact original
task_plan.md (SHA256 verified identical): a fresh DeepSeek session immediately reproduces the same 400 again.
- On the restored failure, logs again show
function_call → developer message from task_plan.md → function_call_output, with identical call IDs and a real successful tool result.
Control workspace:
- Same machine, same DeepSeek model, same OpenCodex, but an empty workspace with no
task_plan.md: 28/28 observed tool-result continuation requests returned HTTP 200, with 0 cases where a developer message appeared between a function_call and its function_call_output.
Model control:
- In the failing workspace,
GLM/glm-5.2 executes the same tool successfully even when developer messages are interleaved between function calls and outputs. So this appears specific to the DeepSeek Responses compatibility path, not the shell command or workspace permissions.
Version
Known reproduction: OpenCodex 2.10.2.
The issue still reproduced immediately after upgrading OpenCodex on 2026-08-08. The latest published release at report time is v2.11.0; the exact post-upgrade local ocx --version output was not captured before filing, so please treat 2.10.2 as the exact confirmed version and v2.11.0 as the likely/current upgraded build pending confirmation.
Codex App on the reproducing machine:
- About version:
26.730.61639 (released 2026-08-05)
- Windows package:
OpenAI.Codex 26.730.8199.0
Operating system
Windows 11 LTSC
PowerShell 7.6.3
Provider and model
Official DeepSeek provider
- Routed model:
deepseek/deepseek-v4-flash
- Adapter:
openai-responses
- Inbound protocol:
responses
- Requested effort:
max
Logs or error output
Representative failing follow-up request:
{
"model": "deepseek-v4-flash",
"provider": "deepseek",
"inboundProtocol": "responses",
"requestedModel": "deepseek/deepseek-v4-flash",
"requestedEffort": "max",
"status": 400,
"errorCode": "invalid_request_error",
"upstreamError": "No tool output found for tool call call_00_...",
"attempts": [
{
"adapter": "openai-responses",
"status": 400,
"sendCount": 1,
"recoveryKinds": []
}
]
}
The immediately preceding request in the same conversation returned HTTP 200 with non-zero output/reasoning tokens. The tool command then executed successfully. The next request reached OpenCodex and upstream, but returned the 400 above.
Detailed local log inspection confirms:
function_call(call_id=call_00_sp4OLJNqwFpIzzZ8jpDl6521)
→ message(role=developer, text verbatim from task_plan.md)
→ function_call_output(call_id=call_00_sp4OLJNqwFpIzzZ8jpDl6521, output=successful command result)
The call IDs are identical; the output is not missing.
Screenshots and supporting files
Available if useful. We have:
- Codex UI screenshots of the tool execution followed by the 400;
- OpenCodex raw log entries for the preceding HTTP 200 and failing HTTP 400;
logs_2.sqlite evidence for the 5/5 failing workspace vs 28/28 successful control workspace;
- ABA reversible test evidence (
task_plan.md present → fail, renamed → pass, restored → fail).
Redacted configuration
The failing machine uses the built-in DeepSeek provider routed through openai-responses. No project-local provider override is involved. The control and failing workspaces share the same global OpenCodex/provider/tool configuration.
No secrets are included in this report.
The workspace has a planning-with-files setup, but inspection showed its PostToolUse hook is not the direct source of the full task_plan.md developer message. The exact Codex-side injection mechanism remains unknown.
Expected behavior
OpenCodex's DeepSeek Responses compatibility path should correctly handle Codex histories where a developer/system message is interleaved between a function_call and the matching function_call_output, or normalize the history into a provider-compatible ordering before forwarding upstream.
At minimum, a valid matching function_call_output with the same call_id and successful tool result should not be treated as missing solely because another message appears between the pair.
Actual behavior
The follow-up request reaches DeepSeek but returns HTTP 400:
No tool output found for tool call <call_id>
This makes DeepSeek unusable as a tool-using executor in affected Codex workspaces while GLM and other paths continue to work.
Checks
References
Related but distinct from #875 (DeepSeek V4 Flash Responses route stalls after tool calls). In this report the follow-up request is sent and reaches upstream, but returns a concrete 400. This matches the "follow-up is sent and 400s" branch discussed during #875 triage rather than the older "no follow-up request is sent" failure mode.
If maintainers want, I can provide a sanitized local capture of the exact continuation input around the function_call / developer message / function_call_output triplet.
Client or integration
Codex App (Windows desktop)
Area
Tools / Responses continuation / provider compatibility
Summary
deepseek/deepseek-v4-flashon the nativeopenai-responsesroute returns HTTP 400 when Codex sends a continuation whose input history contains a developermessagebetween afunction_calland its matchingfunction_call_output.The tool itself executes successfully, the
function_call_outputis present, and thecall_idmatches exactly. The failure is structural/interleaving-related:Upstream error:
This is reproducible and reversible in one workspace. The developer message content is sourced verbatim from a local
task_plan.mdcontext file. Temporarily renaming that file makes the same DeepSeek tool call succeed; restoring it makes the 400 return immediately.Important nuance: the exact Codex-side mechanism that injects this developer message is not yet identified. We initially suspected a planning-with-files
PostToolUsehook, but static inspection ruled that out as the direct source: that hook only emits a short fixed reminder and does not readtask_plan.md. The failing request nevertheless contains a developer message matching the beginning oftask_plan.mdverbatim.Reproduction
Environment A (failing workspace):
task_plan.mdand where the current Codex context-injection setup causes part of that file to appear as a developer message in Responses history.deepseek/deepseek-v4-flashwith Max effort./v1/responsesrequest is sent, but the relevant input order is:A/B/ABA validation on the same workspace:
task_plan.mdpresent: failure reproduced deterministically (5/5 observed failures in prior sessions).task_plan.md→task_plan.md.disabled, leavingprogress.md,findings.md,AGENTS.md, hooks, model, workspace and OpenCodex unchanged: the same single-tool DeepSeek test succeeds.task_plan.md(SHA256 verified identical): a fresh DeepSeek session immediately reproduces the same 400 again.function_call → developer message from task_plan.md → function_call_output, with identical call IDs and a real successful tool result.Control workspace:
task_plan.md: 28/28 observed tool-result continuation requests returned HTTP 200, with 0 cases where a developer message appeared between afunction_calland itsfunction_call_output.Model control:
GLM/glm-5.2executes the same tool successfully even when developer messages are interleaved between function calls and outputs. So this appears specific to the DeepSeek Responses compatibility path, not the shell command or workspace permissions.Version
Known reproduction: OpenCodex 2.10.2.
The issue still reproduced immediately after upgrading OpenCodex on 2026-08-08. The latest published release at report time is v2.11.0; the exact post-upgrade local
ocx --versionoutput was not captured before filing, so please treat 2.10.2 as the exact confirmed version and v2.11.0 as the likely/current upgraded build pending confirmation.Codex App on the reproducing machine:
26.730.61639(released 2026-08-05)OpenAI.Codex 26.730.8199.0Operating system
Windows 11 LTSC
PowerShell 7.6.3
Provider and model
Official DeepSeek provider
deepseek/deepseek-v4-flashopenai-responsesresponsesmaxLogs or error output
Representative failing follow-up request:
{ "model": "deepseek-v4-flash", "provider": "deepseek", "inboundProtocol": "responses", "requestedModel": "deepseek/deepseek-v4-flash", "requestedEffort": "max", "status": 400, "errorCode": "invalid_request_error", "upstreamError": "No tool output found for tool call call_00_...", "attempts": [ { "adapter": "openai-responses", "status": 400, "sendCount": 1, "recoveryKinds": [] } ] }The immediately preceding request in the same conversation returned HTTP 200 with non-zero output/reasoning tokens. The tool command then executed successfully. The next request reached OpenCodex and upstream, but returned the 400 above.
Detailed local log inspection confirms:
The call IDs are identical; the output is not missing.
Screenshots and supporting files
Available if useful. We have:
logs_2.sqliteevidence for the 5/5 failing workspace vs 28/28 successful control workspace;task_plan.mdpresent → fail, renamed → pass, restored → fail).Redacted configuration
The failing machine uses the built-in DeepSeek provider routed through
openai-responses. No project-local provider override is involved. The control and failing workspaces share the same global OpenCodex/provider/tool configuration.No secrets are included in this report.
The workspace has a planning-with-files setup, but inspection showed its
PostToolUsehook is not the direct source of the fulltask_plan.mddeveloper message. The exact Codex-side injection mechanism remains unknown.Expected behavior
OpenCodex's DeepSeek Responses compatibility path should correctly handle Codex histories where a developer/system message is interleaved between a
function_calland the matchingfunction_call_output, or normalize the history into a provider-compatible ordering before forwarding upstream.At minimum, a valid matching
function_call_outputwith the samecall_idand successful tool result should not be treated as missing solely because another message appears between the pair.Actual behavior
The follow-up request reaches DeepSeek but returns HTTP 400:
This makes DeepSeek unusable as a tool-using executor in affected Codex workspaces while GLM and other paths continue to work.
Checks
function_callandfunction_call_outputuse the samecall_id.References
Related but distinct from #875 (
DeepSeek V4 Flash Responses route stalls after tool calls). In this report the follow-up request is sent and reaches upstream, but returns a concrete 400. This matches the "follow-up is sent and 400s" branch discussed during #875 triage rather than the older "no follow-up request is sent" failure mode.If maintainers want, I can provide a sanitized local capture of the exact continuation input around the
function_call/ developermessage/function_call_outputtriplet.