Bug: Codex session resume fails with `Invalid 'input[x].content': array too long` due to incompatible reasoning items in rollout JSONL
What version of the Codex App are you using (From “About Codex” dialog)?
26.721.81911
What subscription do you have?
plus
What platform is your computer?
_No response_
What issue are you seeing?
Bug: Codex session resume fails with Invalid 'input[x].content': array too long due to incompatible reasoning items in rollout JSONL
Description
When resuming an existing Codex session, Codex fails with the following error:
Invalid 'input[7].content': array too long.
Expected an array with maximum length 0, but got an array with length 1 instead.
This is not caused by exceeding the context window or token limit.
The issue appears to be caused by incompatible reasoning items written into the local session history (rollout-*.jsonl) by a third-party Responses API compatible provider.
After switching back to the official OpenAI API endpoint, Codex reloads the existing session history and sends the persisted items for replay. The official Responses API rejects the stored reasoning.content format because reasoning items should not contain a content array.
---
Environment
- Codex CLI version:
<version> - OS:
<OS> - API provider:
- Created session with: third-party OpenAI-compatible Responses API provider
- Resumed session with: official OpenAI API
---
Steps to reproduce
- Configure Codex to use a third-party OpenAI-compatible API provider.
- Start a Codex session.
- Generate responses that contain reasoning items.
- Allow Codex to save the session locally.
- Switch the configuration back to the official OpenAI API endpoint.
- Resume the previous session.
Expected:
- Codex should either migrate incompatible history entries or skip unsupported fields.
Actual:
Codex fails while replaying the stored history:
Invalid 'input[7].content': array too long.
Expected an array with maximum length 0, but got an array with length 1 instead.
````
---
## Root cause
The affected `rollout-*.jsonl` contains entries like:
```json
{
"type": "response_item",
"payload": {
"type": "reasoning",
"content": [
{
"type": "reasoning_text",
"text": "..."
}
]
}
}
````
The third-party provider writes `reasoning.content` as an array.
However, when the official Responses API validates the replayed history, `reasoning` items do not accept content arrays:
Expected:
```json
{
"type": "response_item",
"payload": {
"type": "reasoning",
"content": null
}
}
Received:
{
"type": "response_item",
"payload": {
"type": "reasoning",
"content": [...]
}
}
The API validation fails because:
Expected an array with maximum length 0
Got an array with length 1
---
Temporary workaround
Manually edit the affected session file:
~/.codex/sessions/**/rollout-*.jsonl
First create a backup.
Then only modify entries where:
type == "response_item"
AND
payload.type == "reasoning"
AND
payload.content is an array
Change:
{
"type": "response_item",
"payload": {
"type": "reasoning",
"content": [...]
}
}
to:
{
"type": "response_item",
"payload": {
"type": "reasoning",
"content": null
}
}
After this change, the session can resume normally.
---
Expected behavior
Codex should handle incompatible persisted session records more gracefully.
Possible solutions:
- Ignore invalid
reasoning.contentfields when loading old sessions. - Sanitize/migrate rollout JSONL before sending history to the Responses API.
- Detect incompatible provider-generated session records and show a clear migration error.
- Avoid persisting provider-specific fields that are not compatible with the official Responses API schema.
---
Additional notes
This issue is easy to confuse with context length problems because it happens during session resume.
However, this is a schema validation error:
- Not related to token count.
- Not related to context window size.
- Not related to prompt length.
The failure occurs because persisted local session data contains a reasoning.content structure that is rejected by the official Responses API.
---
What steps can reproduce the bug?
Steps to reproduce
- Configure Codex CLI to use a third-party OpenAI-compatible Responses API provider.
- Start a new Codex session and have a normal conversation. The provider writes response items into the local Codex session history.
- Check the generated session file:
~/.codex/sessions/<session-id>/rollout-*.jsonl
````
The file contains entries similar to:
```json
{
"type": "response_item",
"payload": {
"type": "reasoning",
"content": [
{
"type": "reasoning_text",
"text": "..."
}
]
}
}
````
4. Switch Codex configuration back to the official OpenAI API endpoint.
5. Resume the previous session using the same session id.
6. Codex attempts to replay the stored history and fails with:
Invalid 'input[7].content': array too long.
Expected an array with maximum length 0, but got an array with length 1 instead.
---
## Session information
Session id:
<insert affected session id here>
Rollout file:
~/.codex/sessions/<session-id>/rollout-<timestamp>.jsonl
---
## Context/token information
This issue is not related to context length.
At the time of failure:
* Context window usage: not exceeded
* Token limit: not exceeded
* Failure occurs during session history validation before model execution
The error is caused by invalid persisted history format, specifically:
payload.type = "reasoning"
payload.content = [...]
which is rejected by the official Responses API schema.
---
## Minimal reproduction
A minimal corrupted rollout entry is:
```json
{
"type": "response_item",
"payload": {
"type": "reasoning",
"content": [
{
"type": "reasoning_text",
"text": "example"
}
]
}
}
When this entry is loaded and replayed through the official Responses API, it produces:
Invalid 'input[x].content':
array too long.
Expected an array with maximum length 0, but got an array with length 1 instead.
Changing:
"content": [...]
to:
"content": null
allows the session to resume normally.
What is the expected behavior?
_No response_
Additional information
_No response_
3 Comments
I’m testing Codex Rescue
0.1.0a3on real persisted-history incompatibilities. Yourreasoning.contentreplay failure is useful because the rollout parses, but the stored item shape becomes invalid when replayed through the official Responses API.Rescue does not rewrite provider-specific history or normalize those reasoning items automatically. I’m trying to validate whether it diagnoses the session conservatively and produces a bounded handoff without mutating the source.
If you still have an affected pre-edit rollout, would you be willing to run:
Sanitized
salvage --fork/verifyoutput would also help. Please don’t post raw reasoning text, rollout contents, provider credentials, DBs, or private paths.https://github.com/shleder/codex-rescue
This is a schema-compatibility trap: the session was written by a third-party Responses-compatible provider that emits
reasoningitems with acontentarray, but the official Responses API requiresreasoningitems to have no content array (max length 0). On resume, Codex replays the persisted items verbatim, so the official API rejects the whole replay at the first incompatible reasoning item — even though the transcript itself is fine.The fix class is to normalize persisted reasoning items on replay (strip the content array, or drop reasoning items that can't round-trip) rather than failing the entire resume. For anyone blocked now, the question is how many such items are in the rollout and whether the durable transcript survives without them — reasoning items are usually reconstructable context, not the work product.
Full disclosure: I maintain codex-rescue (https://github.com/shleder/codex-rescue).
codex-rescue doctor --latestflags schema-incompatible records like non-round-trippable reasoning items, andsalvageextracts the durable history into a clean fork read-only-first, so you can recover the actual conversation without the provider-specific reasoning payloads that the official API rejects.verifyconfirms the salvaged session parses before you resume on it.For the provider-switch and incompatible reasoning JSONL case, please check whether the bounded opaque diagnosis identifies the affected rollout without attempting a rewrite.
Thanks for the detailed report. This is a good candidate for a bounded recovery check. Vetto 0.2.0-alpha.2 is available from npm and adds a read-only, copy-only Codex rescue adapter. It does not resume Codex, edit rollout files, or write vendor SQLite. On a disposable copy, try:
npm install --global @shleddy/vetto@next;vetto rescue --adapter codex --root <CODEX_HOME> --json scan; then use the exact returned key withdiagnoseandsnapshot ... --output ./vetto-recovery/session.jsonl. Please report OS, Codex/Vetto versions, sanitized JSON, and source SHA-256 before/after; never upload raw transcripts, auth/config, prompts, or tokens. An explicit unavailable/unsupported result is useful too.