responses: 400 'array too long' when history contains a reasoning item with non-empty content
Summary
Codex API (openai_responses) requests 400 with All target providers failed when the translated request contains a reasoning item whose content array is non-empty. The upstream rejects it because the Responses API requires a reasoning item's content to be empty (max length 0).
Upstream error
Invalid 'input[39].content': array too long.
Expected an array with maximum length 0, but got an array with length 1 instead.
type: invalid_request_error
param: input[39].content
code: array_above_max_lengthReproduction
Request model: "gpt-5.6-luna" (Codex API profile) with streaming. The offending item is index 39 in the input array:
{
"type": "reasoning",
"id": "rs_9a5d56e5879d4fb5855a9a7c7783f75c",
"summary": [],
"content": [
{ "type": "reasoning_text", "text": "We need respond, need clarify what content wrong..." }
],
"encrypted_content": null
}The content field holds a single reasoning_text block, which this Responses API endpoint does not allow on a reasoning input item (it only accepts summary and/or encrypted_content). Any history containing a translated Claude thinking block produces this and 400s deterministically.
Root cause — lives in @the-next-ai/ai-gateway (NOT this repo)
The OpenAI Responses translation emits reasoning text into the content array of reasoning input items. The culprit is buildOpenAIResponsesReasoningInputItem in:
The-NeXT-AI/ai-gateway → src/adapters/builtins/target/openai-responses.ts (line ~694)
...(reasoning.text
? {
content: [
{ type: 'reasoning_text', text: reasoning.text }
]
}
: {}),CCR just consumes this package (@the-next-ai/ai-gateway@^1.0.18). A proper root fix belongs upstream there — e.g. fold reasoning.text into summary (which the endpoint accepts) rather than emitting a non-empty content.
This repo additionally carries a defensive stripUnsupportedOpenAiRequestParameters in packages/core/src/gateway/upstream/executor.ts for the chat-protocol thinking-block case (#1702). It currently only strips thinking/redacted_thinking blocks from messages and deletes top-level thinking/reasoning_split params — it does not touch the Responses-protocol input array, so a reasoning item with non-empty content survives. A belt-and-suspenders strip here (drop content on type === "reasoning" input items) would also prevent this without waiting on an ai-gateway release.
Suggested fix
- Primary (root cause): fix
buildOpenAIResponsesReasoningInputIteminThe-NeXT-AI/ai-gatewayto emit reasoning text assummaryinstead ofcontent. - Defensive (this repo): extend
stripUnsupportedOpenAiRequestParametersto dropcontentontype === "reasoning"items in the Responsesinputarray.
Environment
- CCR via host migration, gateway 3456 / management 3459
- Profile: Codex, provider
codex-api::openai_responses, modelgpt-5.6-luna - Related prior fix: #1686 / #1702 (Anthropic thinking blocks in chat message history → 400), same family but distinct trigger — this is the Responses
inputarray.
Source: musistudio/claude-code-router