Skip to content

Codex remote compaction deadlocks when input_image payloads remain in compacted replacement history #24388

Description

@micrenda

What version of Codex CLI is running?

codex-cli 0.133.0

What subscription do you have?

Pro Lite

Which model were you using?

gpt-5.5 with reasoning_effort=xhigh

What platform is your computer?

Linux 6.12.85+deb13-amd64 x86_64 unknown

What terminal emulator and version are you using (if applicable)?

GNOME Terminal, TERM=xterm-256color, COLORTERM=truecolor. No tmux/screen/zellij for the checked command environment. The affected sessions were long-lived local Codex app-server sessions launched through a wrapper, not ordinary one-off terminal chats.

Codex doctor report

{
    "schemaVersion": 1,
    "generatedAt": "1779667950s since unix epoch",
    "overallStatus": "fail",
    "codexVersion": "0.133.0",
    "checks": {
      "app_server.status": {
        "id": "app_server.status",
        "category": "app-server",
        "status": "ok",
        "summary": "background server is not running",
        "details": {
          "control socket": "/home/mrenda/.codex/app-server-control/app-server-control.sock",
          "daemon state dir": "/home/mrenda/.codex/app-server-daemon",
          "mode": "ephemeral",
          "pid file": "/home/mrenda/.codex/app-server-daemon/app-server.pid (missing)",
          "settings": "/home/mrenda/.codex/app-server-daemon/settings.json (missing)",
          "status": "not running",
          "update-loop pid file": "/home/mrenda/.codex/app-server-daemon/app-server-updater.pid (missing)"
        },
        "remediation": null,
        "durationMs": 0
      },
      "auth.credentials": {
        "id": "auth.credentials",
        "category": "auth",
        "status": "ok",
        "summary": "auth is configured",
        "details": {
          "auth env vars present": "OPENAI_API_KEY",
          "auth file": "/home/mrenda/.codex/auth.json",
          "auth storage mode": "File",
          "stored API key": "false",
          "stored ChatGPT tokens": "true",
          "stored agent identity": "false",
          "stored auth mode": "chatgpt"
        },
        "remediation": null,
        "durationMs": 0
      },
      "config.load": {
        "id": "config.load",
        "category": "config",
        "status": "ok",
        "summary": "config loaded",
        "details": {
          "CODEX_HOME": "/home/mrenda/.codex",
          "config.toml": "/home/mrenda/.codex/config.toml",
          "config.toml parse": "ok",
          "cwd": "/home/mrenda/projects/kuzys",
          "model": "gpt-5.5",
          "model provider": "openai",
          "sqlite home": "/home/mrenda/.codex"
        },
        "remediation": null,
        "durationMs": 0
      },
      "installation": {
        "id": "installation",
        "category": "install",
        "status": "ok",
        "summary": "installation looks consistent",
        "details": {
          "PATH codex #1": "/usr/local/bin/codex",
          "managed by npm": "true",
          "managed package root": "/usr/local/lib/node_modules/@openai/codex",
          "npm update target": "/usr/local/lib/node_modules/@openai/codex"
        },
        "remediation": null,
        "durationMs": 392
      },
      "runtime.provenance": {
        "id": "runtime.provenance",
        "category": "runtime",
        "status": "ok",
        "summary": "running npm on linux-x86_64",
        "details": {
          "platform": "linux-x86_64",
          "version": "0.133.0"
        },
        "remediation": null,
        "durationMs": 0
      },
      "state.paths": {
        "id": "state.paths",
        "category": "state",
        "status": "ok",
        "summary": "state paths and databases are inspectable",
        "details": {
          "CODEX_HOME": "/home/mrenda/.codex (dir)",
          "active rollout files": "191 files, 5226839601 total bytes, 27365652 average bytes",
          "state DB": "/home/mrenda/.codex/state_5.sqlite (file)",
          "state DB integrity": "ok"
        },
        "remediation": null,
        "durationMs": 385
      },
      "terminal.env": {
        "id": "terminal.env",
        "category": "terminal",
        "status": "ok",
        "summary": "terminal metadata was detected",
        "details": {
          "COLORTERM": "truecolor",
          "terminal": "GNOME Terminal",
          "terminal size": "80x24"
        },
        "remediation": null,
        "durationMs": 2
      }
    }
  }

What issue are you seeing?

Long-lived Codex sessions can become unable to resume after remote pre-turn compaction fails with context_length_exceeded.

The affected sessions had input_image payloads preserved inside the latest rollout type=compacted record, under payload.replacement_history.

When Codex later attempted remote pre-turn compaction, those image payloads were included in the compaction request. The request exceeded the model context window, and the session could not
continue.

User-facing error:

Codex ran out of room in the model's context window. Start a new thread or clear earlier history before retrying.

Error running remote compact task:
{
  "error": {
    "message": "Your input exceeds the context window of this model. Please adjust your input and try again.",
    "type": "invalid_request_error",
    "param": "input",
    "code": "context_length_exceeded"
  }
}

Logs included:

codex_core::compact_remote: remote compaction failed
compact_error.code = context_length_exceeded
Failed to run pre-sampling compact

Example logged sizes:

failing_compaction_request_model_visible_bytes=19638335
failing_compaction_request_model_visible_bytes=13626592
failing_compaction_request_model_visible_bytes=9091729
failing_compaction_request_model_visible_bytes=2172694

This creates a deadlock: the session needs compaction to continue, but compaction cannot run because its own input is too large.

What steps can reproduce the bug?

Uploaded thread: 019e0a2b-ffe3-7332-9276-6f6832f8680d

A minimal structural reproduction is:

  1. Use a long-lived Codex session that includes image inputs/screenshots.
  2. Let Codex perform remote compaction.
  3. Inspect the latest rollout type=compacted record in ~/.codex/sessions/....
  4. Confirm that payload.replacement_history contains a user message with content parts including input_image.
  5. Continue the session until Codex tries pre-turn remote compaction again.
  6. Observe remote compaction failing with context_length_exceeded.

Problematic data shape:

{
  "type": "compacted",
  "payload": {
    "replacement_history": [
      {
        "type": "message",
        "role": "user",
        "content": [
          { "type": "input_text", "text": "..." },
          { "type": "input_image", "image_url": "data:image/png;base64,..." },
          { "type": "input_text", "text": "..." }
        ]
      }
    ]
  }
}

Observed affected local threads contained:

- 2 image payloads / ~530 KB image JSON
- 4 image payloads / ~669 KB image JSON
- 9 image payloads / ~2.0 MB image JSON
- 21 image payloads / ~9.2 MB image JSON

After manually replacing only those input_image parts in the latest compacted replacement history with small text markers, the sessions were able to resume without creating new threads.

Uploaded thread 019e0a2b-ffe3-7332-9276-6f6832f8680d contains the investigation and mitigation discussion. The actual affected private rollout files cannot be uploaded because they contain private
session data.



### What is the expected behavior?

Remote compaction should not preserve raw historical `input_image` payloads indefinitely inside active compacted replacement history.

Expected behavior would be one of:

1. omit `input_image` parts from compacted replacement history;
2. replace historical image payloads with lightweight markers;
3. summarize image existence without keeping base64/data URL payloads;
4. strip image payloads before sending history to the remote compaction model;
5. provide a built-in recovery path if compaction fails due to oversized historical payloads.

A session should not become permanently unable to resume because the compaction request itself exceeds context.



### Additional information

Local mitigation used successfully:

1. Back up `~/.codex`.
2. Create a single-file backup of the affected rollout.
3. Modify only the latest `type=compacted` record.
4. Inside `payload.replacement_history`, replace only `input_image` parts with small textual markers.
5. Leave thread id, DB metadata, message order, summaries, text content, and session pointers unchanged.
6. Validate JSONL after modification.

After this surgical repair, affected sessions resumed successfully without starting new threads.

This strongly suggests that preserved `input_image` payloads inside compacted replacement history are the direct trigger.

Privacy note: I cannot provide full rollout files because they contain private session data. I can provide redacted JSON shapes, exact log lines, structural counts, before/after hashes, and
details of the successful mitigation.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    CLIIssues related to the Codex CLIbugSomething isn't workingcontextIssues related to context management (including compaction)sessionIssues involving session (thread) management, resuming, forking, naming, archiving

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions