missing field content HTTP 400 - Codex
Quick fix
Replace content:null with an empty string in CC Switch to fix strict upstream rejections.
Symptom
Section titled “Symptom”messages[1]: missing field `content` at line 1 column 34911When forwarding via cc-switch (v3.19.x - v3.20.0) Responses→Chat conversion path (`apiFormat=openai_chat`) to third-party upstreams that strictly parse JSON Schema (e.g., Agnes, Yunzhou Public Welfare), title generation sub-requests initiated by Codex Desktop or multi-turn tool call scenarios trigger HTTP 400 errors.
The root cause lies in flaws in the internal conversion logic of cc-switch: 1. In `responses_message_item_to_chat_message`, when the input message item lacks a `content` field, the code executes `.unwrap_or(Value::Null)`, resulting in `"content": null` in the output JSON. 2. In `collapse_system_messages_to_head`, for messages where role is system but content is not a string (null or array), the merging logic does not match, causing the message to be retained and passed through unchanged. 3. In `flush_pending_tool_calls`, fixed production includes assistant messages containing `"content": null`.
Although OpenAI specification allows `content` to be null in tool_calls scenarios, many non-OpenAI upstreams (e.g., gateways based on serde) directly error out upon encountering null values with "missing field content" or "invalid content" during deserialization.
Modify the conversion logic in cc-switch source code to replace all occurrences producing `content: null` with an empty string. Specific locations involved: 1. `responses_message_item_to_chat_message`: Change `unwrap_or(Value::Null)` to `unwrap_or(Value::String(String::new()))`. 2. `collapse_system_messages_to_head`: Ensure system messages with non-string content are correctly handled or discarded to prevent passing through null. 3. `flush_pending_tool_calls`: Change the fixed `content: null` to an empty string.
// src-tauri/src/proxy/providers/transform_codex_chat.rs// 修复点 1: responses_message_item_to_chat_messagelet content = item.get("content").map(|value| responses_content_to_chat_content(chat_role, value)).unwrap_or(Value::Null);let content = item.get("content").map(|value| responses_content_to_chat_content(chat_role, value)).unwrap_or(Value::String(String::new()));// 修复点 2 & 3: 确保 flush_pending_tool_calls 和 collapse_system_messages_to_head 不输出 null contentIf you cannot modify the source code immediately, use a local reverse proxy (such as Nginx or a simple Node.js/Python script) to intercept outbound requests from cc-switch, replace all `"content": null` in the JSON body with `"content": ""`, and then forward to the upstream. This serves as a temporary mitigation.
Affected Versions
Section titled “Affected Versions”Source Issues
Section titled “Source Issues”This page is distilled from 2 real issues
- Why does Claude Code not have this issue?
- Claude Code typically uses Anthropic's native API format or different conversion paths; its request body structure handles null content more tolerantly, or its internal message building logic avoids generating empty system messages. This issue primarily affects scenarios using Codex and passing through Responses→Chat conversion.
- Will I get this error if my upstream is the official OpenAI API?
- No. The official OpenAI API has explicit compatibility handling for `content: null` (especially in tool_calls scenarios). Therefore, only third-party gateways or self-built upstreams that are very strict about JSON deserialization and do not support null values will trigger this error.
- Are there other options besides modifying the source code?
- Yes. You can use a local reverse proxy as middleware to automatically replace `content: null` with `content: ""` in the request body. This was mentioned in Issue #6033 as an effective temporary mitigation measure.
Related problems
Section titled “Related problems”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.