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
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
- The machine became extremely sluggish and many windows showed "Not Responding" while Codex was open or when selecting this thread.
- Opening/clicking the image-heavy thread could freeze the Codex Desktop UI for minutes.
- After moving the rollout out of
~\.codex\sessionsand editingsession_index.jsonl, Codex became responsive again. - 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.jsonlentries existed, but the UI did not surface the thread as expected.
Mitigation I used locally
To recover the app, I had to manually:
- Move/quarantine the original 183 MB rollout.
- Edit
C:\Users\<user>\.codex\session_index.jsonlto remove or restore matching entries. - Create a slimmed rollout where large inline image fields were replaced with a small placeholder.
- 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:
- Opening a thread should not parse/render all inline image payloads synchronously on the UI path.
- Very large
image_url/payload.imagesstrings should be lazy-loaded, omitted from sidebar/preview computation, or replaced with lightweight references. - 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.
- 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.
- 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.imagesfields 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:
- image-heavy rollouts can freeze/hang the app before the 512 MB hard crash threshold, and
- sidebar/session recovery is fragile after a user manually quarantines or slims a problematic rollout.
6 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
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:
OpenAI.Codex_26.527.3686.0_x64__2p2nqsd0c76g0C:\Program Files\WindowsApps\OpenAI.Codex_<version>_x64__2p2nqsd0c76g0\app\Codex.exeObserved:
%USERPROFILE%\.codex\sessionsrestored responsiveness.102.44 MB, smaller than my previous~183 MBcase, but still problematic enough to require external cleanup.Sanitized stats from the latest rollout:
Largest records:
Important isolation detail:
response_itemandevent_msgforms.compactedevent can then carry prior image-heavy history again insidepayload.replacement_history; in this repro, one compacted line alone was24.207 MB.%USERPROFILE%\.codex\session_index.jsonlstill 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:
data:imagestrings in durable rollout JSONL when a file/blob reference or content hash would work.compacted.payload.replacement_history; retain lightweight references or placeholders.response_itemandevent_msgrecords, or apply a per-record/per-field byte cap before persistence.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.
Additional macOS data point from Codex Desktop release
26.707.72221/ bundled CLI0.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_imageon two ordinary local PNG files.Observed result:
custom_tool_call_outputcontainedinput_imageitems backed by inlinedata:image/png;base64,...URLs.2,553,323characters.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:
custom_tool_call_output.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.
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
26.707.7222126.5.2(25F84)arm64019f60d0-0894-70e2-9e4d-3cb458c734a4Reproduction
Sanitized rollout evidence
The six
input_imageitems 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.
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_imageinternally.Environment
26.707.9981.025H2, build26200.8737, x64Sequence
execcustom-tool calls internally invokedview_imagewhile inspecting ordinary local project material.input_imageitems as inlinedata:image/png;base64,...URLs. All four were stored withdetail: "original".Sanitized rollout measurements
3,899,327bytes (about 3.72 MiB)179010274, across twocustom_tool_call_outputrecords3,247,112(about 83.3% of the complete rollout size)2,134,024charactersinput_image.image_url:2,133,578characters1,114,430charactersinput_image.image_urlvalues:432,818,388,686, and292,030characters (1,113,534total)40,097charactersThe 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
Configuration finding
I initially considered
tool_output_token_limitas a local mitigation, but the current truncation implementation applies its remaining budget toInputTextwhile preservingInputImage.image_urlitems unchanged:https://github.com/openai/codex/blob/1bbdb32789e1f79932df44941236ea3658f6e965/codex-rs/utils/output-truncation/src/lib.rs#L83-L145
Therefore lowering
tool_output_token_limitwould truncate ordinary diagnostic text but would not cap these inline image payloads.Expected fail-soft behavior
input_image.image_urlfields before rollout persistence and Desktop hydration.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_imagecalls were enough to leave the task permanently unopenable from the Desktop UI.Adding another sanitized Windows reproduction on Codex Desktop Store build 26.707.12708.0 (Windows x64).
Observed:
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:
Related reports: #18629, #24388, #24550.