Claude Code session imports ignore compaction and exceed the Responses input item limit

Open 💬 1 comment Opened Jul 22, 2026 by mh0pe

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?

  1. Create or use a Claude Code project session JSONL with enough ordinary user/assistant records to exceed 16,384 model input items.
  2. Include a normal Claude compaction pair in the source history:
  • a system record with subtype: "compact_boundary";
  • the following user record with isCompactSummary: true and the replacement summary in message.content.
  1. Import Claude Code sessions through Codex Desktop's external-agent migration.
  2. 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 classify isCompactSummary;
  • codex-rs/external-agent-migration/src/sessions/export.rs, which emits one model-visible ResponseItem per 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.

View original on GitHub ↗

1 Comment

mh0pe · 1 month ago

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.