Skip to content

Messages with role 'tool' must be a response to a preceding message with 'tool_calls' (Codex)

Quick fix

In cc-switch, toggle the "local routing" switch off and on again to temporarily recover; this is a proxy internal state bug that recurs.

Error output
CC Switch local proxy failed while handling Codex endpoint /responses. Provider: DeepSeek; model: gpt-5.5; upstream_status: HTTP 400; cause: Messages with role 'tool' must be a response to a preceding message with 'tool_calls'

This error occurs when the cc-switch local proxy forwards Codex /responses requests (in the issue: cc-switch 3.16.4 + Windows + DeepSeek upstream). When the proxy converts Codex conversation history to the upstream format, it produces a message with role 'tool' that is not preceded by a corresponding assistant message with 'tool_calls', so the upstream (e.g., DeepSeek) fails validation and returns HTTP 400.

Per the issue analysis, the suspected root cause is that streamed tool_calls deltas get truncated or overwritten by empty deltas, so the assistant(tool_calls) message and subsequent tool messages received by the upstream no longer match; another possibility is that in thinking mode reasoning_content is not fully carried into the next turn and is rejected by DeepSeek. The same problem has a subtler variant: the model makes no tool calls at all, replies with a very short message and ends with end_turn, with no errors in the log; the two symptoms alternate. Note that the issue comments also contain unrelated error variants (e.g., 401 Unauthorized, 502 Bad Gateway, 400 from function schema validation failure); those are upstream or configuration issues, not the tool message ordering error covered here.

  1. Open cc-switch and find the "local routing" switch.

  2. Turn the switch off, then turn it back on (i.e., toggle off → on once).

  3. No need to restart the terminal or Codex; retry the request directly in Codex — multiple users confirmed immediate recovery.

  4. Note this is only a temporary workaround; the problem recurs after some time. When it recurs, repeat the toggle. A real fix requires cc-switch to fix the proxy internal state issue.

ToolCodex
Versioncc-switch 3.16.4
PlatformsWindows
What if it still doesn't work after toggling local routing off and on?
Some in the issue reported it still failed after the first toggle but worked after a second toggle; others found their case was actually an upstream gateway problem (see QuantumNous/new-api#6038), not this bug. Check whether your error text exactly matches 'tool' must be a response to a preceding message with 'tool_calls'.
Why does the model sometimes skip tool calls and end with a short reply instead of returning HTTP 400?
This is a subtler variant of the same problem: after streamed tool_calls deltas are truncated, the model makes no tool calls, ends with end_turn, and logs no error. Toggling local routing off and on also temporarily recovers from this.
Do I need to enable routing or switch to the native responses format?
Some users noted that this error may occur when routing is not enabled, or when the native responses format is selected while routing is on. Check whether these two settings match your upstream.
Are 401, 502, or 'Invalid schema for function' the same problem?
No. 401 Unauthorized is usually an upstream authentication issue, 502 is a gateway error, and schema-related 400 is a function definition problem. Their cause texts differ and require separate investigation of upstream configuration.

This is an unofficial community wiki with no affiliation to the cc-switch authors or the project itself. Its content is compiled from the project's public GitHub issues. This site distributes no software.