# Codex desktop main-process crash: `RangeError: Invalid string length` when loading sessions whose rollout JSONL exceeds V8's max string length

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

What version of the Codex App are you using (From “About Codex” dialog)?

  • OS: Windows 11 (x64) - Install: Microsoft Store — C:\Program Files\WindowsApps\OpenAI.Codex_<version>_x64__2p2nqsd0c76g0\app\ - Versions reproduced on: 26.506.2212.0 and 26.506.3741.0 (auto-update did not fix) - Config: model = "gpt-5.5", model_reasoning_effort = "xhigh", windows.sandbox = "elevated"

What subscription do you have?

Pro

What platform is your computer?

Windows 11

What issue are you seeing?

Codex desktop main-process crash: RangeError: Invalid string length when loading sessions whose rollout JSONL exceeds V8's max string length

Severity

High. Crash blocks startup. The error is shown in a modal dialog that cannot be dismissed (clicking OK reopens it / Codex is unresponsive); the only way out is to kill every Codex process via Task Manager. Once a session's rollout file passes ~512 MB on disk, opening Codex hangs / crashes 100% of the time. The session — and any work in progress in it — becomes unreachable from the UI.

Environment

  • OS: Windows 11 (x64)
  • Install: Microsoft Store — C:\Program Files\WindowsApps\OpenAI.Codex_<version>_x64__2p2nqsd0c76g0\app\
  • Versions reproduced on: 26.506.2212.0 and 26.506.3741.0 (auto-update did not fix)
  • Config: model = "gpt-5.5", model_reasoning_effort = "xhigh", windows.sandbox = "elevated"

Summary

The Electron main process consumes stdout from a child process (the Codex primary runtime) and concatenates the data into a single JavaScript string in the od.write aggregator. When the cumulative string passes V8's max single-string length (~512 MB on 64-bit, 2^29 - 24 bytes for one-byte strings), String.prototype.concat / += throws RangeError: Invalid string length. The exception is uncaught in the main process, so Electron surfaces the generic "A JavaScript error occurred in the main process" dialog and the app never finishes initializing.

The trigger in practice is a session whose rollout file ~/.codex/sessions/<YYYY>/<MM>/<DD>/rollout-*.jsonl has grown past ~512 MB. This is easy to hit when a single thread is used heavily for image generation, because each generated image is embedded as base64 (≈1–2 MB per image) directly inline in the rollout JSONL. After ~300–500 images in one thread, the file crosses the limit.

Stack trace (verbatim from the error dialog)

Uncaught Exception:
RangeError: Invalid string length
   at od.write (C:\Program Files\WindowsApps\OpenAI.Codex_26.506.3741.0_x64__2p2nqsd0c76g0\app\resource...:7111)
   at Socket.onStdoutData (C:\Program Files\WindowsApps\OpenAI.Codex_26.506.3741.0_x64__2p2nqsd0c76g0\app\resource...:3865)
   at Socket.emit (node:events:508:28)
   at addChunk (node:internal/streams/readable:563:12)
   at readableAddChunkPushByteMode (node:internal/streams/readable:514:3)
   at Readable.push (node:internal/streams/readable:394:5)
   at Pipe.onStreamRead (node:internal/stream_base_commons:189:23)

The trace path is unambiguous: Pipe.onStreamRead → Readable.push → Socket.emit('data') → Socket.onStdoutData → od.write. The crash is not in plugin code, model code, or rendering — it is in the stdout aggregator on the main process, attempting to grow a string past V8's limit.

Reproduction

  1. Use Codex on Windows. In a single thread, run an image-generation workflow that embeds base64 image data into the session rollout (any image-gen plugin will do — the trigger is base64 size, not the source).
  2. Continue in the same thread until C:\Users\<user>\.codex\sessions\<YYYY>\<MM>\<DD>\rollout-*.jsonl exceeds ~512 MB on disk. (In my case, ~300–500 images depending on dimensions.)
  3. Close Codex. Reopen.
  4. The "A JavaScript error occurred in the main process" dialog appears with the stack trace above. Clicking OK does nothing useful; the only way to recover is to End Task on all Codex / codex processes via Task Manager.

Reproduces 100% on my machine. I have hit it twice now in two weeks; six rollouts in my sessions/ folder grew past the limit. Sizes I observed: 506.8 MB, 786.7 MB, 963.5 MB, 1050.3 MB, 1050 MB, 1601 MB.

Expected behavior

Either:

  • Codex loads sessions of arbitrary size successfully (preferred — see fix #1 below), or
  • Codex detects the oversized rollout, refuses to load that one session with a clear message, and continues to start normally so the user retains access to all other threads.

Actual behavior

  • Main process crashes during startup with the stack above.
  • Modal error dialog cannot be dismissed.
  • Codex is fully unresponsive; multiple Codex / codex child processes remain running (in my last incident, six processes, ~3.4 GB RSS combined).
  • All threads — not just the bloated one — are inaccessible until the user manually moves the offending file out of sessions/.

Root cause analysis

V8 caps single-string length at 2^29 - 24 bytes (~512 MB) for one-byte strings, halved for two-byte strings. Reference: v8/include/v8-primitive.h kMaxLength.

The Socket.onStdoutData handler in Codex's main process accumulates the runtime subprocess's stdout into a single string buffer (visible in the trace as od.write). For sessions with rollout JSONL >512 MB, the subprocess streams the file's contents through stdout (likely as part of a "load this session" request), and the cumulative buffer overflows V8's limit.

The deeper design issue: the rollout JSONL format embeds base64 image data inline. Generated images are typically also written to ~/.codex/generated_images/, so the same bytes are duplicated in two places — but only the JSONL embed is what triggers the crash, because that's what gets pumped through stdout on session load.

Suggested fixes (in order of robustness)

  1. Stream-parse rollouts. JSONL is line-delimited; the runtime should emit one record per chunk and the main process should parse incrementally rather than buffering the entire file as one string. This eliminates the V8 limit as a constraint entirely.
  2. Cap and chunk the stdout aggregator. In od.write, when the buffer crosses some threshold (say 256 MB), flush the accumulated content to the consumer and reset, instead of growing forever. JSON message framing (length-prefixed or NDJSON) on the IPC channel would make this trivial.
  3. Catch the RangeError at the boundary and surface a useful error to the user ("Session 'X' could not be loaded — file too large, see <link>") rather than crashing the main process. This alone would unblock users and let them at least see/use other threads.
  4. Stop embedding image bytes in rollouts. Store images only in generated_images/ and reference them from the JSONL by path or content hash. Rollouts would shrink ~99% for image-gen workflows. (This is the right long-term fix; users who generate hundreds of images in one thread will keep producing >512 MB rollouts otherwise.)
  5. Add a periodic rollout-size warning in the UI ("This thread's transcript is 380 MB and may not load on next launch — start a new thread or contact support"). Soft mitigation but very cheap to add.

Workaround (for users hitting this now)

Until a fix ships, users can recover access by manually archiving the oversized rollout:

  1. End Task on all Codex / codex processes in Task Manager.
  2. In C:\Users\<user>\.codex\sessions\, locate the largest rollout-*.jsonl (sort by size). Anything >400 MB is a risk; anything >512 MB is a guaranteed crash.
  3. Move the file out of sessions/ to any other location.
  4. Edit C:\Users\<user>\.codex\session_index.jsonl and delete the line whose id matches the rollout's filename UUID. (Make a .bak first.)
  5. Reopen Codex — it should start cleanly. The archived thread is no longer in the UI but the data is preserved on disk.

Additional context

  • logs_*.sqlite in ~/.codex/ also grew to 2+ GB on my machine, contributing to slow startup but not the crash itself. Some kind of log rotation cap would be welcome.
  • Orphan ..codex-global-state.json.tmp-<timestamp>-<uuid> files accumulate in ~/.codex/ after crashes (the atomic-write tempfile is never cleaned up). Minor, but worth a sweep on startup.

What steps can reproduce the bug?

Codex desktop main-process crash: RangeError: Invalid string length when loading sessions whose rollout JSONL exceeds V8's max string length

Severity

High. Crash blocks startup. The error is shown in a modal dialog that cannot be dismissed (clicking OK reopens it / Codex is unresponsive); the only way out is to kill every Codex process via Task Manager. Once a session's rollout file passes ~512 MB on disk, opening Codex hangs / crashes 100% of the time. The session — and any work in progress in it — becomes unreachable from the UI.

Environment

  • OS: Windows 11 (x64)
  • Install: Microsoft Store — C:\Program Files\WindowsApps\OpenAI.Codex_<version>_x64__2p2nqsd0c76g0\app\
  • Versions reproduced on: 26.506.2212.0 and 26.506.3741.0 (auto-update did not fix)
  • Config: model = "gpt-5.5", model_reasoning_effort = "xhigh", windows.sandbox = "elevated"

Summary

The Electron main process consumes stdout from a child process (the Codex primary runtime) and concatenates the data into a single JavaScript string in the od.write aggregator. When the cumulative string passes V8's max single-string length (~512 MB on 64-bit, 2^29 - 24 bytes for one-byte strings), String.prototype.concat / += throws RangeError: Invalid string length. The exception is uncaught in the main process, so Electron surfaces the generic "A JavaScript error occurred in the main process" dialog and the app never finishes initializing.

The trigger in practice is a session whose rollout file ~/.codex/sessions/<YYYY>/<MM>/<DD>/rollout-*.jsonl has grown past ~512 MB. This is easy to hit when a single thread is used heavily for image generation, because each generated image is embedded as base64 (≈1–2 MB per image) directly inline in the rollout JSONL. After ~300–500 images in one thread, the file crosses the limit.

Stack trace (verbatim from the error dialog)

Uncaught Exception:
RangeError: Invalid string length
   at od.write (C:\Program Files\WindowsApps\OpenAI.Codex_26.506.3741.0_x64__2p2nqsd0c76g0\app\resource...:7111)
   at Socket.onStdoutData (C:\Program Files\WindowsApps\OpenAI.Codex_26.506.3741.0_x64__2p2nqsd0c76g0\app\resource...:3865)
   at Socket.emit (node:events:508:28)
   at addChunk (node:internal/streams/readable:563:12)
   at readableAddChunkPushByteMode (node:internal/streams/readable:514:3)
   at Readable.push (node:internal/streams/readable:394:5)
   at Pipe.onStreamRead (node:internal/stream_base_commons:189:23)

The trace path is unambiguous: Pipe.onStreamRead → Readable.push → Socket.emit('data') → Socket.onStdoutData → od.write. The crash is not in plugin code, model code, or rendering — it is in the stdout aggregator on the main process, attempting to grow a string past V8's limit.

Reproduction

  1. Use Codex on Windows. In a single thread, run an image-generation workflow that embeds base64 image data into the session rollout (any image-gen plugin will do — the trigger is base64 size, not the source).
  2. Continue in the same thread until C:\Users\<user>\.codex\sessions\<YYYY>\<MM>\<DD>\rollout-*.jsonl exceeds ~512 MB on disk. (In my case, ~300–500 images depending on dimensions.)
  3. Close Codex. Reopen.
  4. The "A JavaScript error occurred in the main process" dialog appears with the stack trace above. Clicking OK does nothing useful; the only way to recover is to End Task on all Codex / codex processes via Task Manager.

Reproduces 100% on my machine. I have hit it twice now in two weeks; six rollouts in my sessions/ folder grew past the limit. Sizes I observed: 506.8 MB, 786.7 MB, 963.5 MB, 1050.3 MB, 1050 MB, 1601 MB.

Expected behavior

Either:

  • Codex loads sessions of arbitrary size successfully (preferred — see fix #1 below), or
  • Codex detects the oversized rollout, refuses to load that one session with a clear message, and continues to start normally so the user retains access to all other threads.

Actual behavior

  • Main process crashes during startup with the stack above.
  • Modal error dialog cannot be dismissed.
  • Codex is fully unresponsive; multiple Codex / codex child processes remain running (in my last incident, six processes, ~3.4 GB RSS combined).
  • All threads — not just the bloated one — are inaccessible until the user manually moves the offending file out of sessions/.

Root cause analysis

V8 caps single-string length at 2^29 - 24 bytes (~512 MB) for one-byte strings, halved for two-byte strings. Reference: v8/include/v8-primitive.h kMaxLength.

The Socket.onStdoutData handler in Codex's main process accumulates the runtime subprocess's stdout into a single string buffer (visible in the trace as od.write). For sessions with rollout JSONL >512 MB, the subprocess streams the file's contents through stdout (likely as part of a "load this session" request), and the cumulative buffer overflows V8's limit.

The deeper design issue: the rollout JSONL format embeds base64 image data inline. Generated images are typically also written to ~/.codex/generated_images/, so the same bytes are duplicated in two places — but only the JSONL embed is what triggers the crash, because that's what gets pumped through stdout on session load.

Suggested fixes (in order of robustness)

  1. Stream-parse rollouts. JSONL is line-delimited; the runtime should emit one record per chunk and the main process should parse incrementally rather than buffering the entire file as one string. This eliminates the V8 limit as a constraint entirely.
  2. Cap and chunk the stdout aggregator. In od.write, when the buffer crosses some threshold (say 256 MB), flush the accumulated content to the consumer and reset, instead of growing forever. JSON message framing (length-prefixed or NDJSON) on the IPC channel would make this trivial.
  3. Catch the RangeError at the boundary and surface a useful error to the user ("Session 'X' could not be loaded — file too large, see <link>") rather than crashing the main process. This alone would unblock users and let them at least see/use other threads.
  4. Stop embedding image bytes in rollouts. Store images only in generated_images/ and reference them from the JSONL by path or content hash. Rollouts would shrink ~99% for image-gen workflows. (This is the right long-term fix; users who generate hundreds of images in one thread will keep producing >512 MB rollouts otherwise.)
  5. Add a periodic rollout-size warning in the UI ("This thread's transcript is 380 MB and may not load on next launch — start a new thread or contact support"). Soft mitigation but very cheap to add.

Workaround (for users hitting this now)

Until a fix ships, users can recover access by manually archiving the oversized rollout:

  1. End Task on all Codex / codex processes in Task Manager.
  2. In C:\Users\<user>\.codex\sessions\, locate the largest rollout-*.jsonl (sort by size). Anything >400 MB is a risk; anything >512 MB is a guaranteed crash.
  3. Move the file out of sessions/ to any other location.
  4. Edit C:\Users\<user>\.codex\session_index.jsonl and delete the line whose id matches the rollout's filename UUID. (Make a .bak first.)
  5. Reopen Codex — it should start cleanly. The archived thread is no longer in the UI but the data is preserved on disk.

Additional context

  • logs_*.sqlite in ~/.codex/ also grew to 2+ GB on my machine, contributing to slow startup but not the crash itself. Some kind of log rotation cap would be welcome.
  • Orphan ..codex-global-state.json.tmp-<timestamp>-<uuid> files accumulate in ~/.codex/ after crashes (the atomic-write tempfile is never cleaned up). Minor, but worth a sweep on startup.

What is the expected behavior?

_No response_

Additional information

_No response_

View original on GitHub ↗

13 Comments

github-actions[bot] contributor · 3 months ago

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

  • #21232
  • #21948
  • #20544

Powered by Codex Action

rdylina · 3 months ago

Related macOS evidence: my failing thread is an 825MB rollout, but I saw a dropped 405MB IPC frame rather than RangeError. Same underlying limit class: full rollout/thread state is being aggregated into huge Electron/JS payloads. Even before a hard V8 string-length crash, the app becomes unusable; it needs size gates and paged/tail-only loading.

rdylina · 3 months ago

Follow-up / PR offer: I read the contribution docs and understand external PRs are invitation-only. If the team thinks this direction fits, I’d be happy to take a stab at an invited PR for the open-source app-server side.

Conceptually, the fix I’d propose is:

  • in no case should opening a thread load the entire transcript into app-server + client state
  • open threads from metadata + the latest tail only, roughly the most recent 100-200 messages or a small byte cap, whichever comes first
  • lazy-load older chunks only when the user scrolls upward / explicitly asks for them
  • compact or summarize the old head for model context instead of treating the full durable transcript as active state
  • keep large tool outputs/artifacts behind references, not inline in normal thread state
  • add hard byte/count limits so thread/read, thread/resume, and stream-state snapshots cannot produce 100MB+ payloads
  • document that Desktop/IDE clients should use paged turns/items and never full-hydrate a completed thread just because it was clicked

The desktop side still needs closed-code changes, but the app-server can provide the safe bounded contract and fail gracefully when a client asks for full hydration of an oversized rollout.

ohnoah · 3 months ago

I hit the same failure class on macOS Codex Desktop.

Environment

  • Codex Desktop for macOS: 26.513.31313
  • Platform: macOS
  • Affected rollout JSONL: ~/.codex/sessions/.../rollout-2026-05-15T08-21-11-019e2a82-ba83-7333-bac7-954d24293676.jsonl
  • Original rollout size: 1,368,538,366 bytes (~1.37 GB)
  • Record count: 23,442 JSONL records

Crash

Electron main-process alert:

Uncaught Exception:
RangeError: Invalid string length
at fd.write (/Applications/Codex.app/Contents/Resources/app.asar/.vite/build/workspace-root-drop-handler-D1HnRjoH.js:292:21)
at Socket.onStdoutData (/Applications/Codex.app/Contents/Resources/app.asar/.vite/build/workspace-root-drop-handler-D1HnRjoH.js:292:4023)
at Socket.emit (node:events:509:28)
at addChunk (node:internal/streams/readable:563:12)
at readableAddChunkPushByteMode (node:internal/streams/readable:514:3)
at Readable.push (node:internal/streams/readable:394:5)
at Pipe.onStreamRead (node:internal/stream_base_commons:189:23)

Observed local behavior

  • Opening/resuming the giant session reproduced the crash.
  • thread/read returned quickly for that conversation.
  • The app-server process then grew to roughly 6-8 GB RSS.
  • I did not see a successful thread/resume completion logged for the affected conversation.
  • This looks consistent with hydrating/serializing the full thread history over stdio as one oversized JSON-RPC line/string, eventually hitting V8's string limit.

Rollout contents / workaround evidence

The bloat was mostly plain tool/result payloads, not encrypted content:

  • event_msg/mcp_tool_call_end: ~698 MB
  • response_item/function_call_output: ~648 MB
  • encrypted_content: ~3.6 MB total, max ~11 KB

A local repair that redacted only oversized plain tool-result strings and replaced oversized inline image_url data with a tiny valid data:image/png;base64,... placeholder reduced the rollout to 71,069,050 bytes. The repaired JSONL kept the same 23,442 records, had no lines over 1 MB, and preserved encrypted-content count/hash exactly.

Expected behavior: Desktop should not crash the Electron main process on a single oversized local session. It should stream/chunk large resume payloads, cap/summarize oversized tool outputs, or fail that one session with a recoverable error while keeping the rest of Desktop usable.

iqqs33i-stack · 2 months ago

Additional macOS reproduction evidence for the same failure class.

Environment

  • Codex Desktop for macOS: 26.608.12217 (CFBundleVersion=3722)
  • Bundled CLI: codex-cli 0.138.0-alpha.7
  • OS: macOS 26.4.1 build 25E253, Apple Silicon / arm64
  • Affected project: local liarsdice project
  • Affected thread/session id: 019ea61c-c900-7980-a2b6-4501d8344757
  • Affected rollout: ~/.codex/sessions/2026/06/08/rollout-2026-06-08T00-22-44-019ea61c-c900-7980-a2b6-4501d8344757.jsonl
  • Rollout size: 1,449,517,542 bytes (~1.35 GiB), 6,430 JSONL records

The thread was a long-running image asset generation/review workflow. The final goal usage reported by Codex was about 7,569,355 tokens. It generated/reviewed many image asset candidates, so the rollout grew very large.

Crash dialog

Uncaught Exception:
RangeError: Invalid string length
at jP.write (/Applications/Codex.app/Contents/Resources/app.asar/.vite/build/src-K8ZToA-n.js:368:21)
at Socket.onStdoutData (/Applications/Codex.app/Contents/Resources/app.asar/.vite/build/src-K8ZToA-n.js:368:4146)
at Socket.emit (node:events:508:28)
at addChunk (node:internal/streams/readable:563:12)
at readableAddChunkPushByteMode (node:internal/streams/readable:514:3)
at Readable.push (node:internal/streams/readable:394:5)
at Pipe.onStreamRead (node:internal/stream_base_commons:189:23)

Local observations

  • This is the same Socket.onStdoutData -> *.write path described in this issue.
  • The app logs for the same day do not contain the literal RangeError text, and no new macOS crash report was found under ~/Library/Logs/DiagnosticReports, so the visible evidence was primarily the Electron uncaught exception dialog plus the oversized rollout.
  • Relevant local app logs around the incident are under ~/Library/Logs/com.openai.codex/2026/06/11/.
  • I am not attaching full logs or the rollout because they may contain local/session content, but the repro data above should confirm that the issue still reproduces on recent macOS builds with oversized image-generation rollouts.

Expected behavior

Same as the original report: Codex Desktop should stream/chunk/cap oversized stdout/session payloads or fail only the affected thread with a recoverable error. A single oversized local rollout should not be able to crash the Electron main process.

thisislvca · 1 month ago

Adding another macOS Desktop reproduction on a newer build, with local repair measurements. This one came from Codex Desktop built-in image generation rather than Computer Use.

Environment:

  • Codex Desktop for macOS: 26.623.101652 (CFBundleVersion=4674)
  • Platform: macOS 15.7.7 (24G720), arm64
  • Failure date: 2026-07-05

Crash / log evidence:

  • Visible Electron main-process dialog:
Uncaught Exception:
RangeError: Invalid string length
at dL.write (/Applications/Codex.app/Contents/Resources/app.asar/.vite/build/src-CoIhwwHr.js:410:21)
at Socket.onStdoutData (...src-CoIhwwHr.js:418:6911)
at Socket.emit (node:events:508:28)
...
  • Local Desktop log for opening the affected thread showed a thread/read response crossing the practical V8/string boundary:
Failed to parse MCP message
errorMessage="Expected ',' or '}' after property value in JSON at position 536870710"
lineBytes=536871005
linePreview={"id":"...","result":{"thread":{"id":"..."

Affected rollout stats before repair:

rollout JSONL size:             1,165,931,575 bytes (~1.1 GB)
JSONL records:                  3,240
separate generated PNG files:   179 files / ~408 MB
image_generation result records 358
inline image result bytes:      1,138,720,392 bytes (~1.09 GiB)

Important duplication detail: each generated image was present once as event_msg / image_generation_end.result and once as response_item / image_generation_call.result, while also being saved as a PNG artifact under the local generated-images directory.

Local recovery that made the rollout small and parseable again:

  1. Backed up the original rollout.
  2. Replaced payload.result for image_generation_end / image_generation_call with a small valid 64x64 PNG base64 string, not an arbitrary text placeholder.
  3. Converted 17 old function_call_output.output values containing input_image / data:image content into text-only omission strings.
  4. Preserved prompts, call ids, timestamps, saved_path, and normal text records.
  5. Re-validated JSONL.

After repair:

rollout JSONL size:             6,096,679 bytes (~5.8 MB)
JSONL records:                  3,240
max JSONL line:                 84,047 bytes
raw data:image records:         0
image_generation result records 358
invalid image result records:   0

This supports the same root cause already described here: Desktop/app-server should not build full thread/read / resume / stream-state payloads that include historical image bytes, and rollout persistence should not store generated image bytes inline and duplicated across event and response surfaces. A built-in repair path that externalizes or schema-safely omits old image payloads would have recovered this thread without manual JSONL surgery.

Coldain · 1 month ago

Current-machine evidence that this size boundary is still reachable in Codex Desktop, even when the app does not immediately crash:

  • macOS 27.0 (26A5388g), Codex Desktop 26.721.41059.
  • ~/.codex/sessions: 122.2 GiB across 1,007 JSONL files.
  • 15 rollout files exceed 512 MiB; 5 exceed 1 GiB; the largest is ~3.8 GiB.
  • A representative 597,936,910-byte image-heavy subagent rollout (CLI 0.145.0-alpha.18) contained:
  • 406.3 MiB of event_msg/image_generation_end
  • 114.4 MiB of response_item/custom_tool_call_output
  • 18.1 MiB of compacted
  • 14.2 MiB of event_msg/mcp_tool_call_end
  • The largest individual JSONL line was 18,742,520 bytes, with repeated multi-megabyte payload.result / image_url strings.

So the immediate crash behavior may have improved in newer builds, but the underlying >512 MiB rollout creation and persistence problem remains. A robust fix should externalize/deduplicate binary payloads before they enter JSONL and keep only bounded references in both the primary rollout and compaction history.

Apex-Studio-He · 1 month ago

Adding a project-scoped new task creation reproduction on the current macOS build. This is a different failure surface from opening/resuming the oversized thread itself: historical oversized threads can prevent an unrelated brand-new task from being created inside the same project.

Environment

  • Codex Desktop: 26.721.41059 (CFBundleVersion=5848)
  • macOS: 15.6.1 (24G90), Apple Silicon
  • Local project with long-running coding + EDA/tool/image workflows

User-visible symptom

  1. Select the affected local project.
  2. Start a new task with a short prompt and a small screenshot.
  3. Task creation fails immediately with the toast:
创建任务时出错
Invalid string length

Creating and using a projectless task with image attachments still works. The failure is scoped to the affected project.

Sanitized local evidence

The project working directory itself is only about 110 MB, so repository size does not explain the string allocation failure.

The project has several historical tasks. Three assigned rollout JSONL files are:

581,598,355 bytes
648,412,129 bytes
1,222,537,823 bytes

Their counts of lines containing one or more of easyeda_canvas_capture, data:image, base64, or image_url are respectively:

502
546
1,092

Maximum JSONL line lengths are approximately 5.39 MB, 6.91 MB, and 3.51 MB. A read-only project/thread listing probe also failed to return within 70 seconds.

I did not repair, delete, or modify any session data before collecting these measurements. I intentionally omitted my local username, absolute paths, project/thread IDs, prompts, images, and raw rollouts.

Why this variant matters

An oversized historical task appears able to poison new task creation for the whole project, even though the new task has no history yet. This suggests that the project/sidebar/new-thread path is hydrating or serializing historical task data instead of using bounded metadata.

My long-running EDA and coding workflows naturally accumulate tool outputs and screenshots. I cannot reasonably control the client's hidden inline image persistence or predict a rollout-size boundary.

Expected behavior

  • Creating a new task should require only bounded project/thread metadata, not full historical rollouts.
  • Historical task lists should be lazy/paged and byte-capped.
  • Inline image/tool payloads should be externalized or deduplicated.
  • One oversized task should fail recoverably without preventing new tasks in the same project.
  • If a size limit is reached, Desktop should show an actionable "history too large" diagnostic instead of Invalid string length.

This also appears related to #24676 and the broader unbounded-session report #25779.

PZZZB · 26 days ago

Additional Windows evidence from a related failure mode:

  • Codex runtime/CLI: 0.146.0-alpha.3.1
  • Model: gpt-5.6-sol
  • A legacy thread's rollout JSONL reached 635,816,094 bytes (about 606.4 MiB).
  • The local threads row reports tokens_used = 504,813,696.
  • The app did not crash in this case. The thread remained listed and its latest turn was still readable and recorded as completed with error: null.
  • However, sending a new composer message to that thread failed with the generic UI error Error submitting message. Fresh threads continued to work.
  • A local logs_2.sqlite entry for the affected thread contains the decisive line: incremental request failed, incompatible request length, shortly after mid-turn context-limit auto-compaction.
  • The thread reader reports the affected thread as notLoaded while still returning its stored turns.

This looks like a pre-crash / alternate oversized-rollout symptom in the same failure class: once the transcript exceeds the V8-sized range, the app can still enumerate/read enough state to show the thread, but the submit/resume path cannot build or transport the next request.

No transcript, thread ID, workspace path, screenshots, or private logs are attached.

pifoub · 26 days ago

Adding current Windows evidence from #31033. This appears to be the same unbounded full-rollout materialization failure, triggered here by /feedback submission rather than ordinary thread loading or resume.

Environment

  • ChatGPT/Codex Desktop: 26.727.6591.0, confirmed current
  • Windows 11 Pro Insider Preview 10.0.26220, build 26220
  • Feedback ID: 019f1a12-0ee3-7d33-b396-899e85e7358a

Failure evidence

The affected task rollout JSONL reached approximately 9.8 GiB.

During the first /feedback session-upload attempt, the Codex desktop log reported:

memory allocation of 10424232598 bytes failed

The retry reported:

memory allocation of 10424232600 bytes failed

Both app-server processes exited with Windows status:

3221226505 / 0xC0000409

The requested allocations closely match the affected task-record size. This strongly suggests that the feedback/session-upload path attempts to materialize the complete rollout as one contiguous allocation rather than streaming, chunking, or applying a bounded history view.

The application displayed Feedback upload failed; retrying consistently terminated ChatGPT with ChatGPT stopped unexpectedly. The application update check confirmed that the installed release was current.

No obvious JSONL corruption was found at the end of the task record.

Related compaction behavior

The same rollout was produced by an automatic-compaction/reconstruction loop:

  • 114 explicit automatic-compaction markers
  • approximately 65 visible protocol lines between compactions on average
  • repeated rereading of the same large source files and tool outputs after each compaction

This appears to connect two defects:

  1. compaction/reconstruction does not bound durable rollout growth;
  2. /feedback crashes while serializing the resulting oversized rollout.

Detailed report and screenshots:

Expected behavior: feedback submission should stream or chunk session data, enforce an upload-size limit, or submit a reduced diagnostic package. A single oversized session should fail recoverably without terminating the app-server or desktop application.

The raw rollout is not posted publicly because it contains private conversation and project data.

Apex-Studio-He · 26 days ago

@pifoub 9.8 GiB is wild. Thanks for documenting this so thoroughly—the near-exact match between the requested allocation and the rollout size is especially convincing. The 114-compaction loop is also a strong clue that rollout growth itself needs to be bounded.

Rememorio · 18 days ago

Additional macOS reproduction: an active oversized session breaks unrelated new-chat creation

I reproduced the same failure class on macOS, with an additional app-wide symptom: the oversized thread did not need to be opened at the time of failure. While it remained active in the background, creating an unrelated new local task failed repeatedly with the toast Invalid string length.

Environment
  • macOS 26.5.2 (25F84), Apple Silicon
  • ChatGPT/Codex Desktop: 26.803.41515 (build 6321)
  • Bundled Codex CLI: 0.147.0-alpha.6.5
  • Bundled Node: v24.14.0
  • buffer.constants.MAX_STRING_LENGTH = 536870888
Oversized active session
  • Rollout size at diagnosis: 834,418,141 bytes (~795.8 MiB)
  • JSONL records: 51,371
  • Largest individual record: ~3.77 MiB
  • The rollout was still growing while the failures occurred.
  • Nine rollouts in the active session store were individually larger than the bundled V8/Node string limit.

A metadata-only byte breakdown of the affected rollout showed that this is not image-generation-specific:

  • event_msg/mcp_tool_call_end: ~583.7 MiB across 4,378 records
  • response_item/custom_tool_call_output: ~86.2 MiB across 8,058 records
  • compacted/message: ~40.8 MiB
  • response_item/function_call_output: ~38.1 MiB

So an ordinary long-running, tool-heavy task can accumulate enough persisted state to trigger the same limit even without one corrupt or exceptionally large JSONL line.

New-task failure

The unrelated new task used a short text-only prompt. The app-server's thread/start response arrived without an error, and the Electron handler then failed:

2026-08-10T07:48:14.820Z info  [AppServerConnection] response_routed ... method=thread/start ... errorCode=null
2026-08-10T07:48:14.821Z error [electron-message-handler] Error creating local task errorMessage="Invalid string length"
2026-08-10T07:48:14.822Z error [electron-message-handler] [Composer] submit failed ... errorMessage="Invalid string length" mode=local

At the same time, the main process continuously logged:

warning [electron-message-handler] Failed to broadcast thread state patches ... errorMessage="Invalid string length"

The new-task failure reproduced four times in about 40 seconds. The UI otherwise remained usable enough to work in another task.

This appears to extend the original report: a hydrated/active oversized rollout can poison Electron state synchronization and block unrelated task creation, without requiring a full startup crash or explicitly opening the oversized task. A single pathological thread should be isolated, size-gated, or tail/paged so unrelated composers and tasks continue to work.

No session contents, prompts, project names, absolute paths, or conversation IDs are included here.

shleder · 14 days ago

A rollout that makes Desktop crash at startup with RangeError: Invalid string length, while the JSONL itself still exists, is a strong recovery-test case. Your six 500 MB–1.6 GB rollouts also give a concrete size boundary.

I’m testing Codex Rescue’s local, bounded inspection on cases like this. It cannot fix Electron’s V8/stdout path or rewrite image history automatically, but it may identify the oversized persisted records without loading them into a Desktop session. The original rollout remains untouched and recovery is fail-closed.

If you retained one affected rollout locally, could you run:

pipx install codex-rescue==0.1.0a3
codex-rescue sessions
codex-rescue doctor --latest

Please share sanitized output only—no raw rollout, images, databases, prompts, paths, or secrets.

https://github.com/shleder/codex-rescue