What version of the Codex App are you using (From “About Codex” dialog)?
Codex Desktop 26.820.60940 (build 7119), with bundled codex-cli 0.150.0-alpha.8.
What subscription do you have?
Not relevant to the failure. It occurs in the local Desktop/app-server task lifecycle before a model request.
What platform is your computer?
Darwin 25.5.0 arm64 arm
What issue are you seeing?
After Stop → edit an earlier user message → Send, Codex Desktop reverts the task's history. The task keeps the same stable thread ID, but its active local rollout JSONL file changes.
If the same task was already open in another top-level Desktop window, that window can retain the original rollout path. Reselecting the task there shows a blank task/plan and repeatedly raises:
Failed to resume chat
cannot resume running thread <thread-id> with stale path:
requested `<original rollout>.jsonl`,
active `<replacement rollout>.jsonl`
The two paths are different valid history files for the same stable thread ID, not alternate spellings of one path.
The window roles are:
- Source window: the window where the user stops the running turn, edits an earlier message, and sends it.
- Stale window: another window that had already loaded the same task before the edit.
Source window Stale window
(same task already loaded) (same task, pre-revert state)
│ │
│ Stop → Edit earlier message → Send │
▼ │
thread/revert │
│ │
├─ stable thread ID retained │
└─ replacement rollout selected │
│
└─ reselect task
│
└─ resume sends original rollout
│
▼
blank task + repeating toast
Local process correlation ties the affected task to the app-server bundled in the standard macOS /Applications/ChatGPT.app. It was not handled by a standalone CLI, IDE extension, Claude process, or separately profiled AI Fleet app. Rollout metadata reports originator: "Codex Desktop" and cli_version: "0.150.0-alpha.8"; app-server telemetry reports client Codex Desktop version 26.820.60940 over stdio.
What steps can reproduce the bug?
- Start Codex Desktop and open an existing local task.
- Open that same task in two distinct top-level Desktop windows. Use Open in New Window if necessary.
- Wait until the task's history is visible in both windows, and keep both open.
- In the source window, submit a message and wait until the turn is running.
- Click Stop.
- Choose Edit on an earlier submitted user message, change it, and click Send.
- Switch to the stale window. Select another task and then reselect the affected task so Desktop attempts to resume it.
- Observe the blank task/plan and repeating Failed to resume chat toast. The toast identifies the pre-edit rollout as
requested and the replacement rollout as active.
The complete failure was observed on the reported task. A separate task independently confirmed the trigger—Stop → edit an earlier message → Send produced a native rpc.method="thread/revert" request—but was not a second independent reproduction of the stale-window toast loop.
What is the expected behavior?
- Every open window showing a task should converge on the active post-revert history.
- A stale window should recover by the stable thread ID and display the active history.
- A retired rollout path should not displace or block the already-loaded logical thread.
- Desktop should not retry the same failed resume indefinitely or produce an unbounded toast loop.
Additional information
Ready implementation PR on a public fork
The implementation is a numbered, reviewable PR at joshmouch/codex#1, rebased onto current upstream main. The current implementation commit is 8549ea49af, and the upstream comparison is ready for an upstream collaborator to open directly against openai/codex.
Suggested repair
The server-side rule should have one owner: when threadId resolves a thread already loaded by app-server, that stable identity is authoritative. path is a mutable rollout locator and should not become a second selector after the live thread has already been found. The PR therefore ignores path in the loaded-thread branch and returns the active rollout path.
The cold-resume boundary remains strict. For an unloaded paginated thread, a supplied path must be current; a stale path is rejected and the client can omit it to resume by stable thread ID. This matches the current upstream behavior added in 0d654e6536.
Desktop should still treat thread/reverted as cross-window cache invalidation, omit experimental thread/resume.path from ordinary ID reattachment, and bound identical failed retries/toasts. Those are defense-in-depth around the unambiguous server rule.
The complete task/thread ID, rollout paths, screenshot, and sanitized local log extracts can be supplied privately if maintainers need them.
This is not the archive/unarchive stale-state case, the Windows \\?\\ path-canonicalization case, or the app://-/index.html new-window bundle-load failure. It occurs on macOS after an explicit history edit and involves two distinct rollout files for one stable thread ID.
What version of the Codex App are you using (From “About Codex” dialog)?
Codex Desktop
26.820.60940(build7119), with bundledcodex-cli 0.150.0-alpha.8.What subscription do you have?
Not relevant to the failure. It occurs in the local Desktop/app-server task lifecycle before a model request.
What platform is your computer?
Darwin 25.5.0 arm64 armWhat issue are you seeing?
After Stop → edit an earlier user message → Send, Codex Desktop reverts the task's history. The task keeps the same stable thread ID, but its active local rollout JSONL file changes.
If the same task was already open in another top-level Desktop window, that window can retain the original rollout path. Reselecting the task there shows a blank task/plan and repeatedly raises:
The two paths are different valid history files for the same stable thread ID, not alternate spellings of one path.
The window roles are:
Local process correlation ties the affected task to the app-server bundled in the standard macOS
/Applications/ChatGPT.app. It was not handled by a standalone CLI, IDE extension, Claude process, or separately profiled AI Fleet app. Rollout metadata reportsoriginator: "Codex Desktop"andcli_version: "0.150.0-alpha.8"; app-server telemetry reports clientCodex Desktopversion26.820.60940over stdio.What steps can reproduce the bug?
requestedand the replacement rollout asactive.The complete failure was observed on the reported task. A separate task independently confirmed the trigger—Stop → edit an earlier message → Send produced a native
rpc.method="thread/revert"request—but was not a second independent reproduction of the stale-window toast loop.What is the expected behavior?
Additional information
Ready implementation PR on a public fork
The implementation is a numbered, reviewable PR at joshmouch/codex#1, rebased onto current upstream
main. The current implementation commit is8549ea49af, and the upstream comparison is ready for an upstream collaborator to open directly againstopenai/codex.Suggested repair
The server-side rule should have one owner: when
threadIdresolves a thread already loaded by app-server, that stable identity is authoritative.pathis a mutable rollout locator and should not become a second selector after the live thread has already been found. The PR therefore ignorespathin the loaded-thread branch and returns the active rollout path.The cold-resume boundary remains strict. For an unloaded paginated thread, a supplied path must be current; a stale path is rejected and the client can omit it to resume by stable thread ID. This matches the current upstream behavior added in
0d654e6536.Desktop should still treat
thread/revertedas cross-window cache invalidation, omit experimentalthread/resume.pathfrom ordinary ID reattachment, and bound identical failed retries/toasts. Those are defense-in-depth around the unambiguous server rule.The complete task/thread ID, rollout paths, screenshot, and sanitized local log extracts can be supplied privately if maintainers need them.
This is not the archive/unarchive stale-state case, the Windows
\\?\\path-canonicalization case, or theapp://-/index.htmlnew-window bundle-load failure. It occurs on macOS after an explicit history edit and involves two distinct rollout files for one stable thread ID.