Claude Code session imports ignore compaction and exceed the Responses input item limit
What issue are you seeing?
External-agent session import treats Claude Code compaction summaries as ordinary user messages. The imported rollout therefore contains every pre- and post-compaction message as model-visible ResponseItems instead of using the source summary as a replacement-history checkpoint.
On the first follow-up to a large imported task, Codex attempts automatic compaction with the entire flattened history. The Responses API rejects the request before it can compact:
Invalid 'input': array too long. Expected an array with maximum length 16384, but got an array with length 76298 instead
The UI then reports automatic compaction, reconnects twice, and ends with:
stream disconnected before completion: websocket closed by server before response.completed
The websocket failure is downstream of the invalid oversized request.
What steps can reproduce the bug?
- Create or use a Claude Code project session JSONL with enough ordinary
user/assistantrecords to exceed 16,384 model input items. - Include a normal Claude compaction pair in the source history:
- a
systemrecord withsubtype: "compact_boundary"; - the following
userrecord withisCompactSummary: trueand the replacement summary inmessage.content.
- Import Claude Code sessions through Codex Desktop's external-agent migration.
- Resume the imported task and send a follow-up message.
In one sanitized reproduction, the imported rollout persisted 76,295 user/assistant ResponseItems. Runtime context added three more items, producing the exact rejected array length of 76,298. A second imported session persisted 17,589 response messages and was already over the API limit before runtime items were added.
What is the expected behavior?
Claude's isCompactSummary record should become a native Codex RolloutItem::Compacted checkpoint with bounded replacement_history. Older records should remain available as visible imported history, while model reconstruction should start from the latest source summary and replay only the post-compaction tail.
Following up on an imported compacted session should not trigger re-compaction of the entire flattened source transcript or exceed the Responses API item limit.
Additional information
Current main still has the flattening behavior in:
codex-rs/external-agent-migration/src/sessions/records.rs, which recognizes user/assistant records but does not classifyisCompactSummary;codex-rs/external-agent-migration/src/sessions/export.rs, which emits one model-visibleResponseItemper parsed message and accumulates token usage across the full import.
Codex resume reconstruction already supports the needed representation: the newest RolloutItem::Compacted with replacement_history becomes the model-history base while older rollout events remain persisted for thread history.
1 Comment
Implementation PR: https://github.com/mh0pe/codex/pull/1
This preserves Claude Code compaction summaries as native Codex compaction checkpoints so imported sessions resume from bounded replacement history instead of replaying every pre-compaction item.