Client or integration
Codex CLI
Area
Provider adapter
Summary
In OpenCodex 2.28.0, OAuth xai/grok-4.5 and xai/grok-4.6 became unusable on the native Responses route. #2147 moved those models off the Chat Completions compatibility wire onto openai-responses passthrough so Codex would not sit blank until reasoning finished (#1886). Chat translation had been sanitizing Codex-private wire extensions as a side effect; passthrough forwards the client's bytes, and xAI rejects the request before inference.
The conversation-killing case is the second turn: Codex replays a reasoning item with "content": null, and xAI returns HTTP 400 while mislabeling the field as a compaction blob. A first-turn namespace / private-tool catalog can 422 the same session before that.
I have already handled this (fix PRs #2217 and #2237). Please assign the issue to @olddonkey.
Reproduction
- Run OpenCodex 2.28.0 with Codex CLI on OAuth
xai/grok-4.5 or xai/grok-4.6 (native /v1/responses, no Chat Completions wire).
- Start a new conversation with the default Codex 0.147+ tool catalog.
- First message is rejected (private
tools[].type = "namespace" / external_web_access).
- After the catalog is lowered, send a second message so Codex replays the previous reasoning item with
"content": null.
Redacted second-request shape:
{
"model": "grok-4.6",
"input": [
{"role": "user", "content": "hello"},
{
"type": "reasoning",
"id": "rs_redacted",
"encrypted_content": "<intact grok blob>",
"content": null
},
{"role": "user", "content": "continue"}
]
}
On a captured failing body: verbatim request → 400; removing only the content key → 200; removing encrypted_content → 400 schema error (blob was intact). Stripping content: null unconditionally repairs Grok and breaks OpenAI, which requires that field.
Version
2.28.0
Operating system
macOS
Provider and model
xai / grok-4.5, xai / grok-4.6
Logs or error output
Argument not supported: external_web_access
{"code":"invalid-argument","error":"Could not decode the compaction blob. Ensure it is unmodified from the compact response."}
The failing request often has no compaction item. xAI names the sibling field, not the null content channel that actually caused the 400.
Redacted configuration
{
"model": "xai/grok-4.6",
"route": "openai-responses",
"auth": "oauth"
}
Checks
Client or integration
Codex CLI
Area
Provider adapter
Summary
In OpenCodex 2.28.0, OAuth
xai/grok-4.5andxai/grok-4.6became unusable on the native Responses route. #2147 moved those models off the Chat Completions compatibility wire ontoopenai-responsespassthrough so Codex would not sit blank until reasoning finished (#1886). Chat translation had been sanitizing Codex-private wire extensions as a side effect; passthrough forwards the client's bytes, and xAI rejects the request before inference.The conversation-killing case is the second turn: Codex replays a reasoning item with
"content": null, and xAI returns HTTP 400 while mislabeling the field as a compaction blob. A first-turn namespace / private-tool catalog can 422 the same session before that.I have already handled this (fix PRs #2217 and #2237). Please assign the issue to @olddonkey.
Reproduction
xai/grok-4.5orxai/grok-4.6(native/v1/responses, no Chat Completions wire).tools[].type = "namespace"/external_web_access)."content": null.Redacted second-request shape:
{ "model": "grok-4.6", "input": [ {"role": "user", "content": "hello"}, { "type": "reasoning", "id": "rs_redacted", "encrypted_content": "<intact grok blob>", "content": null }, {"role": "user", "content": "continue"} ] }On a captured failing body: verbatim request → 400; removing only the
contentkey → 200; removingencrypted_content→ 400 schema error (blob was intact). Strippingcontent: nullunconditionally repairs Grok and breaks OpenAI, which requires that field.Version
2.28.0
Operating system
macOS
Provider and model
xai / grok-4.5, xai / grok-4.6
Logs or error output
{"code":"invalid-argument","error":"Could not decode the compaction blob. Ensure it is unmodified from the compact response."}The failing request often has no compaction item. xAI names the sibling field, not the null
contentchannel that actually caused the 400.Redacted configuration
{ "model": "xai/grok-4.6", "route": "openai-responses", "auth": "oauth" }Checks