Codex Desktop should fail-soft on control characters and oversized historical tool output
What version of the Codex App are you using (From “About Codex” dialog)?
Codex Desktop package observed locally: OpenAI.Codex_26.513.3673.0_x64__2p2nqsd0c76g0
CLI / app-server observed in session metadata: 0.131.0-alpha.9
What subscription do you have?
ChatGPT / Codex Desktop account. Exact template subscription value is not important for this local renderer issue.
What platform is your computer?
Windows x64, PowerShell, locale zh-CN.
What issue are you seeing?
Some existing Codex Desktop threads can still open to the generic error page even when the underlying rollout JSONL is valid and does not contain the known standalone ::git-*{cwd="C:\..."} directive crash trigger from #22968 / #22977.
In one affected recovery/diagnostics thread, local validation showed:
- the rollout JSONL parsed successfully line by line;
state_5.sqliteandsession_index.jsonlhad matching entries;model_providerwas valid;- no
function_call_output.outputfields were non-strings; - no standalone directive-shaped lines like
::name{...}remained in any JSON string field.
However, the same thread still failed to render in the Desktop UI. The remaining suspicious payloads were historical tool/event render strings:
- several strings contained raw C0 control characters or ANSI escape sequences from terminal/binary-search output;
- one historical tool/event render string was approximately 1 MB;
- a few additional tool render strings were hundreds of KB.
A local repair that made the thread render-safe was:
- back up the affected JSONL;
- remove ANSI terminal color sequences from historical tool output strings;
- escape raw C0 control characters (except normal
\n,\r,\t) into visible text such as\x00; - truncate only oversized historical tool/event render payloads, keeping the start/end plus a placeholder note;
- revalidate the JSONL.
After repair, validation for that thread showed:
parse errors: 0
standalone directive string fields: 0
control/ANSI string fields: 0
huge tool-render string fields: 0
This strongly suggests that thread replay/rendering should treat historical tool output as untrusted text. A valid JSONL transcript should not become impossible to open because a past tool output captured terminal control characters, binary-ish data, or an oversized render string.
What steps can reproduce the bug?
A minimal reproduction should be possible on Windows by creating or importing a historical Codex rollout JSONL containing a tool output / event result string with one or more of:
- raw
\^@/ C0 control characters in a JSON string; - ANSI escape sequences such as
\^[[31;1m; - a very large single tool result string (hundreds of KB to 1 MB+).
Then reopen the thread in Codex Desktop.
Observed local symptoms:
- backend/data checks pass;
- JSONL parsing succeeds;
- the Desktop UI still shows the generic “Oops / error occurred” page for that thread.
What is the expected behavior?
Codex Desktop should open the conversation and fail-soft on problematic historical tool render blocks. For example:
- strip or safely escape terminal control characters before rendering;
- cap rendered size for historical tool output blocks;
- show a collapsed placeholder for binary/oversized output;
- continue rendering the rest of the conversation;
- log the exact offending JSONL line / field path for recovery.
What actually happens?
The entire conversation can become inaccessible from the UI even though the stored transcript is structurally valid and most user/assistant messages are fine.
Why this matters
Users can lose access to long-running project history because a previous diagnostic command captured binary-ish logs, terminal color codes, or very large output. This is different from repository corruption or model/provider configuration. It is a renderer/replay robustness issue.
Related issues
Related but distinct from:
- #22968
- #22977
Those isolate a Markdown directive parser crash with standalone ::git-* lines containing Windows paths. This issue is about a second class of historical payloads: valid JSON strings in tool/event output that contain control characters or oversized render text.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗