Codex Desktop hangs when opening an image-heavy session rollout (~183 MB, huge inline image_url records), and the thread becomes hard to recover from the sidebar

Open 💬 6 comments Opened May 27, 2026 by starmiaoa
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

Issue draft for openai/codex

Title

Codex Desktop hangs when opening an image-heavy session rollout (~183 MB, huge inline image_url records), and the thread becomes hard to recover from the sidebar

Body

What version of the Codex App are you using?

OpenAI Codex Desktop, Microsoft Store install:

  • Package: OpenAI.Codex
  • Version: 26.519.5221.0
  • Package full name: OpenAI.Codex_26.519.5221.0_x64__2p2nqsd0c76g0
  • Install location pattern: C:\Program Files\WindowsApps\OpenAI.Codex_<version>_x64__2p2nqsd0c76g0\

What platform is your computer?

Windows 11 x64

  • Microsoft Windows NT 10.0.26200.0 x64

What subscription do you have?

plus

What issue are you seeing?

Codex Desktop can become extremely slow or fully "Not Responding" when opening a long, image-heavy local thread whose rollout JSONL contains large inline image payloads.

This is related to image-heavy-session issues such as:

However, my case reproduced well below the ~512 MB V8 string-limit crash described in #22004. The problematic rollout was about 183 MB on disk, but still made the app/UI effectively unusable when the thread was selected. The thread also became difficult to recover from the sidebar after manually moving/slimming the rollout and restoring the index.

Local evidence

Problematic session rollout:

C:\Users\<user>\.codex\sessions\2026\05\18\rollout-2026-05-18T18-03-42-<thread-id>.jsonl

Original file stats before mitigation:

File size:             182.8 MB
Lines:                 41,361
Total chars:           188,255,915
Max single JSONL line: 6,850,815 chars
Lines > 20k chars:     1,205
Lines > 100k chars:    88
Lines > 500k chars:    19
Lines > 1m chars:      14
JSON parse errors:     0

Largest records were response_item / event_msg records containing inline image data:

Line 24062: response_item, 6,850,815 chars
  $.payload.content[5].image_url length: 2,561,406
  $.payload.content[2].image_url length: 2,128,902

Line 24063: event_msg, 6,849,389 chars
  $.payload.images[1] length: 2,561,406
  $.payload.images[0] length: 2,128,902

Line 9126: response_item, 5,086,077 chars
  $.payload.content[2].image_url length: 5,085,746

Line 9127: event_msg, 5,085,951 chars
  $.payload.images[0] length: 5,085,746

The issue is not that ordinary text was too long. The heavy records were mainly base64/data-URL image strings stored inline in the JSONL.

Observed behavior

  1. The machine became extremely sluggish and many windows showed "Not Responding" while Codex was open or when selecting this thread.
  2. Opening/clicking the image-heavy thread could freeze the Codex Desktop UI for minutes.
  3. After moving the rollout out of ~\.codex\sessions and editing session_index.jsonl, Codex became responsive again.
  4. After creating a slimmed copy of the rollout, restoring the index, and even creating a cloned recovery thread with a new id/title, the thread still did not reliably show up in the desktop sidebar. The local files and session_index.jsonl entries existed, but the UI did not surface the thread as expected.

Mitigation I used locally

To recover the app, I had to manually:

  1. Move/quarantine the original 183 MB rollout.
  2. Edit C:\Users\<user>\.codex\session_index.jsonl to remove or restore matching entries.
  3. Create a slimmed rollout where large inline image fields were replaced with a small placeholder.
  4. Prune older detailed records while keeping a recent compacted summary and recent records.

After replacing large inline images and pruning old records:

Slimmed file size:     41.43 MB
Lines:                 16,670
Max single JSONL line: 78,692 chars
Lines > 100k chars:    0

This made the underlying local data much less dangerous, but the thread still could not reliably be recovered from the sidebar.

Expected behavior

Codex Desktop should remain responsive when a local session contains many images or large image payloads.

At minimum:

  1. Opening a thread should not parse/render all inline image payloads synchronously on the UI path.
  2. Very large image_url / payload.images strings should be lazy-loaded, omitted from sidebar/preview computation, or replaced with lightweight references.
  3. The app should not embed full image bytes into the rollout JSONL if the images are already available elsewhere; the rollout should store file paths/content hashes instead.
  4. If a rollout is too large or malformed for the UI to load safely, Codex should show a recoverable error for that one thread, not make the whole app unresponsive.
  5. The sidebar/session index should have a robust recovery path after a user manually quarantines or slims a problematic rollout.

Why this matters

This can make a user's long-running thread unrecoverable from the UI even though the local session data still exists on disk. In my case, the practical workaround was to manually extract a textual summary from the JSONL and move to a new thread.

Suggested fixes

  • Do not inline base64/data-URL image bytes in rollout JSONL; store references to generated image files instead.
  • Stream-parse JSONL records and avoid building/rendering huge strings on the Electron UI path.
  • Apply hard caps to image_url / payload.images fields before sending records to the renderer.
  • Use virtualized rendering for history items and lazy-load old image-heavy turns only when expanded.
  • Add a built-in "repair/export summary" flow for sessions that are too large to open.
  • Add a warning when a rollout exceeds a threshold such as 50 MB / 100 MB / 250 MB.

Additional notes

I can provide exact sanitized stats and the PowerShell scripts used to identify the large records, but I cannot upload the raw rollout because it contains private conversation history and image data.

Optional comment for an existing issue

This may be a useful data point for #21232 / #22004:

I reproduced a similar Codex Desktop freeze on Windows with a rollout that was only ~183 MB, well below the ~512 MB V8 string-limit crash case. The file contained 41k JSONL records and 14 individual lines over 1 million characters. The largest records were response_item / event_msg entries containing inline image_url / payload.images strings, with single image strings up to ~5.1 million characters.

After replacing large inline image fields and pruning old records, the rollout dropped to 41.43 MB and max line length dropped to 78,692 chars. This made the local data safer, but the thread still did not reliably reappear in the desktop sidebar even after restoring session_index.jsonl entries and adding a cloned recovery thread. So there may be two related issues:

  1. image-heavy rollouts can freeze/hang the app before the 512 MB hard crash threshold, and
  2. sidebar/session recovery is fragile after a user manually quarantines or slims a problematic rollout.

View original on GitHub ↗

6 Comments

github-actions[bot] contributor · 1 month ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #23257
  • #24318
  • #24100
  • #24388
  • #24550

Powered by Codex Action

VVittgenstein · 1 month ago

Adding a fresh Windows repro on a newer Store build. This looks like the same image-heavy rollout/session class, with one extra amplification detail: compaction can retain inline image data inside replacement_history.

Environment:

  • Codex Desktop Store package: OpenAI.Codex_26.527.3686.0_x64__2p2nqsd0c76g0
  • App executable path class: C:\Program Files\WindowsApps\OpenAI.Codex_<version>_x64__2p2nqsd0c76g0\app\Codex.exe
  • Platform: Windows x64
  • Date observed: 2026-06-01 local time

Observed:

  • Codex Desktop repeatedly became slow / stuck / Windows "Not Responding" around image-heavy threads.
  • Quarantining large rollout JSONL files out of %USERPROFILE%\.codex\sessions restored responsiveness.
  • The latest repro rollout was only 102.44 MB, smaller than my previous ~183 MB case, but still problematic enough to require external cleanup.

Sanitized stats from the latest rollout:

File size:                    102.44 MB
JSONL lines:                  982
Lines > 1 MB:                 17
Lines > 5 MB:                 7
Lines containing data:image:  31
Bytes in image-containing lines: 100.37 MB
data:image URI occurrences:   51
Unique image data URIs:       34
Total data:image URI bytes:   100.26 MB
response_item user image lines: 14
event_msg user_message image lines: 14
compacted records:            2
bytes in compacted records:   24.74 MB
largest single record:        24.207 MB compacted record with 16 image refs

Largest records:

Line 757: compacted, 24.207 MB, 16 image refs
Line 403: event_msg/user_message, 6.486 MB, 1 image ref
Line 402: response_item/message, 6.486 MB, 1 image ref
Line 393: response_item/message, 6.403 MB, 1 image ref
Line 394: event_msg/user_message, 6.403 MB, 1 image ref
Line 675: event_msg/user_message, 6.121 MB, 1 image ref
Line 674: response_item/message, 6.121 MB, 1 image ref

Important isolation detail:

  • The file was not large because of ordinary text.
  • Almost the entire file size was inline base64 image data.
  • The same user-provided screenshots appear to be persisted in both response_item and event_msg forms.
  • The compacted event can then carry prior image-heavy history again inside payload.replacement_history; in this repro, one compacted line alone was 24.207 MB.
  • After quarantining the rollout file, %USERPROFILE%\.codex\session_index.jsonl still contained stale entries for the quarantined thread id. Removing those stale index lines after backing up the index prevents the sidebar/thread list from retaining entries for missing dangerous rollouts.

Suggested fixes / guards:

  • Do not store raw image bytes as inline data:image strings in durable rollout JSONL when a file/blob reference or content hash would work.
  • Do not include raw image data in compacted.payload.replacement_history; retain lightweight references or placeholders.
  • Avoid duplicating the same image payload across response_item and event_msg records, or apply a per-record/per-field byte cap before persistence.
  • Keep sidebar/thread-list state metadata-only and avoid loading image-heavy turns unless the user explicitly opens/expands them.
  • Add a built-in repair/archive flow for oversized or image-heavy sessions so users do not need to manually move JSONL files and edit session_index.jsonl.

Privacy note: I am intentionally not uploading the raw rollout, screenshots, sqlite databases, or unsanitized logs because they contain private conversation/image data.

hug1997 · 6 days ago

Additional macOS data point from Codex Desktop release 26.707.72221 / bundled CLI 0.144.2:

A short diagnostic turn became image-heavy from one tool output

This was not initially a long, image-heavy conversation. During diagnosis, a custom tool invoked view_image on two ordinary local PNG files.

Observed result:

  • The resulting custom_tool_call_output contained input_image items backed by inline data:image/png;base64,... URLs.
  • The serialized output for that single tool result was approximately 2,553,323 characters.
  • After this large inline image output entered the turn, there was no subsequent assistant completion before the user aborted the turn several minutes later.
  • Repeating the diagnostic pattern in another short thread again left the thread active after the image tool output.

This shows that image payload amplification can be introduced by the tool-result path even when the original thread is short. It is consistent with the broader issue described here: raw inline image bytes become part of persisted/rehydrated session state and can make the current turn difficult to continue or recover.

Suggested safeguards:

  • Persist a lightweight image artifact reference instead of a full base64 data URL in custom_tool_call_output.
  • Apply a hard byte cap/redaction rule before image tool results enter rollout JSONL or model context.
  • Avoid duplicating the same image bytes across structured tool output, event messages, and context replay.
  • Surface a clear size warning/error instead of leaving the task silently active.

The related end-user image-input latency and cold-start reproduction is tracked separately in #33018.

No private image content, local paths, or raw rollout records are included in this comment.

917Dhj · 6 days ago

Adding a smaller macOS reproduction on the current Codex Desktop release. This appears to be the same image-heavy session rehydration/rendering class, but it triggers with a rollout of only 2.64 MB.

Environment

  • Codex Desktop: 26.707.72221
  • macOS: 26.5.2 (25F84)
  • Architecture: Apple Silicon / arm64
  • Thread ID for OpenAI diagnostics: 019f60d0-0894-70e2-9e4d-3cb458c734a4

Reproduction

  1. Select the affected interrupted thread in the Codex Desktop sidebar.
  2. The desktop UI becomes unresponsive immediately.
  3. Reopening the same thread reproduces the freeze consistently; other threads remain usable.

Sanitized rollout evidence

Rollout size:                 2,636,902 bytes
JSONL records:               86
Largest single record:       2,183,452 characters
Largest record type:         response_item / custom_tool_call_output
Tool output items:           7 (1 input_text + 6 input_image)
Image dimensions:            910 x 1287 each
Serialized tool output:      2,183,147 characters
Share of rollout in record:  ~82.8%

The six input_image items are inline data URLs produced by one tool result. The thread is not corrupt: a metadata/thread read through the app interface parses it in roughly 0.1 seconds, and the associated child-agent thread is completed. The freeze occurs when the Desktop app opens/rehydrates the affected thread, which points to the renderer/history-loading path rather than an active backend task.

This is notable because the failure occurs at ~2.64 MB, far below the 102–183 MB Windows rollouts previously reported here. It also complements the recent macOS tool-output report above: in this case the persisted thread reliably freezes specifically when reopened.

Expected behavior: image-heavy tool results should be virtualized/lazy-loaded or represented by lightweight artifact references, and one problematic history item should not block the entire UI.

Privacy note: I am intentionally not including the original request text, conversation content, local paths, images, or raw JSONL.

chbq · 5 days ago

On Windows Codex Desktop, task also becomes unopenable after first-turn view_image output (~3.7 MiB rollout)

Adding a current Windows reproduction that closely matches the recent small-rollout reports here, with one important distinction: this was not an image-generation request or a long image-heavy workflow. A brand-new local-project task became image-bearing only because its first diagnostic turn used view_image internally.

Environment

  • Codex Desktop 26.707.9981.0
  • Windows 25H2, build 26200.8737, x64
  • Local-project task

Sequence

  1. I created a new Desktop task in a local project.
  2. The first user message referenced/imported a small ChatGPT conversation: 10 messages (about 5 turns), with a serialized referenced-message payload of approximately 27,133 characters.
  3. During the first Codex turn, two exec custom-tool calls internally invoked view_image while inspecting ordinary local project material.
  4. Those two results persisted four input_image items as inline data:image/png;base64,... URLs. All four were stored with detail: "original".
  5. The turn completed. Later, selecting the task from the sidebar caused the UI to refresh/reload and the Desktop window to close.
  6. Restarting Codex did not recover it: selecting the same task repeated the failure. Other tasks remained usable after the affected task was archived through a background/app-server path.

Sanitized rollout measurements

  • Complete archived rollout: 3,899,327 bytes (about 3.72 MiB)
  • JSONL records: 179
  • JSON parse errors: 0
  • Visible user/assistant messages: 10
  • Stored tool-output events: 27
  • Inline PNG data URLs: 4, across two custom_tool_call_output records
  • Total characters in those four image URLs: 3,247,112 (about 83.3% of the complete rollout size)
  • Largest JSONL record: 2,134,024 characters
  • One input_image.image_url: 2,133,578 characters
  • Second-largest JSONL record: 1,114,430 characters
  • Three input_image.image_url values: 432,818, 388,686, and 292,030 characters (1,113,534 total)
  • Largest ordinary text result: about 40,097 characters

The imported conversation itself was small. The rollout became large primarily because four full PNG data URLs were embedded in tool-result history during the first turn.

For completeness, two smaller text fields contain form-feed characters (U+000C): 13 occurrences in a 33,614-character field and 2 occurrences in a 1,331-character field. I found no ANSI escape sequences. I cannot completely exclude those control characters as a renderer edge case, but they do not explain the size concentration in the two image-bearing records.

Additional observations

  • A background read of the task succeeds quickly, so the rollout is not generally unreadable and its JSONL is valid.
  • I found no matching Windows Application Error/Hang event and no Crashpad dump for the occurrence, despite the visible window closing/reloading.
  • This occurred with only four tool-result images and a 3.72 MiB rollout, not after sustained image generation or a 100+ MiB session.

Configuration finding

I initially considered tool_output_token_limit as a local mitigation, but the current truncation implementation applies its remaining budget to InputText while preserving InputImage.image_url items unchanged:

https://github.com/openai/codex/blob/1bbdb32789e1f79932df44941236ea3658f6e965/codex-rs/utils/output-truncation/src/lib.rs#L83-L145

Therefore lowering tool_output_token_limit would truncate ordinary diagnostic text but would not cap these inline image payloads.

Expected fail-soft behavior

  • Store tool-result images out of line and persist lightweight blob/file references instead of full Base64 data URLs.
  • Apply a hard byte cap or safe replacement rule to structured input_image.image_url fields before rollout persistence and Desktop hydration.
  • Avoid hydrating or decoding all historical full-resolution tool images synchronously when opening a task.
  • If one history item cannot be rendered, open the task with a placeholder rather than refreshing or closing the whole app.
  • Provide a recovery action such as Open without images/tool output, Export, or Repair task.
  • Log the offending event path, media type, detail mode, and serialized size.

Current workaround

The affected task had to be archived without opening it. I can provide the task/thread ID privately through a safe diagnostics channel, but I would prefer not to post the raw rollout publicly because it contains local project and conversation content.

This appears to extend the existing reports from long/image-heavy sessions to a normal first-turn diagnostic workflow on Windows, where two internal view_image calls were enough to leave the task permanently unopenable from the Desktop UI.

easonlao · 4 days ago

Adding another sanitized Windows reproduction on Codex Desktop Store build 26.707.12708.0 (Windows x64).

Observed:

  • A single active rollout grew to approximately 131.56 MB.
  • It contained only 2 image-generation call records but 144 input_image/data:image records.
  • The thread became increasingly slow or unresponsive and could remain stuck in a thinking/tool state.
  • No large ordinary text payload was involved; the growth was dominated by inline image data and repeated image-input history.
  • Archiving the thread moved the rollout out of the active session set and reduced the active session footprint from roughly 298 MB to 167 MB. The archived rollout was preserved; no raw session or image data is being uploaded.

This is consistent with the existing reports that image bytes are persisted inline in replayable rollout history, and that later image reads or replays can amplify the problem even when the number of generation calls is small.

Potential mitigations:

  • Persist generated/tool images out-of-line and keep only a file/blob reference, hash, or bounded placeholder in rollout history.
  • Do not retain raw input_image payloads in compacted replacement history.
  • Avoid duplicating the same image payload across event representations.
  • Lazy-load historical images and provide a recoverable warning or repair/archive action when a rollout becomes image-heavy.

Related reports: #18629, #24388, #24550.