You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
macOS app: voice transcription send fails with 'Error starting conversation' and creates zombie thread #11902
What version of the Codex App are you using (From “About Codex” dialog)?
Codex macOS app: 26.212.1823 (build 661)
What subscription do you have?
ChatGPT Pro
Which model were you using?
Model: GPT-5.3-Codex
Reasoning: Extra High
What platform is your computer?
macOS 26.3 (Build 25D125), Apple Silicon (arm64)
What issue are you seeing?
When using the macOS app voice transcription (mic), after transcribing and pressing Send on a new thread, the UI briefly flashes the transcribed text into the chat input, attempts to submit it, then errors immediately with the toast: Error starting conversation.
Despite the error, the app still creates a thread entry which then loads forever. These stuck threads also cannot be archived.
What steps can reproduce the bug?
Open the Codex macOS app
Start a new thread
Use voice transcription (mic), speak a prompt
Press Send
Observe instant toast Error starting conversation
Observe a new thread is created but is stuck loading forever and cannot be archived
What is the expected behavior?
Transcribed text should send normally and start the conversation
If the conversation fails to start, the app should not create a broken thread, or should allow it to be recovered/archived
Additional information
This is reproducible for me on a new thread (not intermittent)
Happy to provide thread IDs and logs via the /feedback slash command if you can confirm what you need
I attempted two PRs (now closed due to invitation-only contribution policy); I pasted the distilled analysis and patch sketches in comments on this issue
Opened PR #11905 to make v1 work even when is missing/null by resolving the rollout from . This should address the stuck/zombie threads being unarchivable (even if the underlying conversation-start error persists).
Follow-up (previous comment got mangled by shell backticks): Opened PR #11905 to make v1 archiveConversation work even when rolloutPath is missing/null by resolving the rollout path from conversationId. This should address the stuck/zombie threads being unarchivable (even if the underlying conversation-start error persists).
This should address the instant “Error starting conversation” path when the v1 newConversation flow ends up starting an ephemeral session (no rolloutPath), which then errors while responding and leaves a zombie thread in the UI.
If you can repro this, can you run the command in Codex to upload logs/session data and then post the thread ID(s) here? Also helpful: the exact Codex macOS app version string from About Codex + your macOS version.
Follow-up: if you can repro this, please run the /feedback slash command in Codex to upload logs/session data and then post the thread ID(s) here. Also helpful: the exact Codex macOS app version string from About Codex + your macOS version.
Heads-up: both PRs (#11905 / #11910) were closed due to the invitation-only contribution policy (see discussions/9956). No worries — here’s the distilled analysis + patch sketch in case the team wants to implement internally.
Root cause candidate for the instant "Error starting conversation" (backend-side)
v1 newConversation/resumeConversation/forkConversation responses always include a required rolloutPath.
If ephemeral=true is set via params.config (or via a profile), Codex intentionally produces SessionConfiguredEvent.rollout_path = None.
The v1 handler then errors while forming the response ("rollout path missing for v1 conversation"), but the thread id has already been created => UI can end up with a "zombie" thread.
Proposed fix (minimal / defensive)
Force ephemeral=false for v1 conversation start/resume/fork by setting ConfigOverrides.ephemeral = Some(false) in the v1 handlers.
Regression test idea: start a v1 newConversation request with config: { ephemeral: true } and assert it still returns an absolute rolloutPath.
in v1 process_new_conversation, handle_resume_conversation, handle_fork_conversation: ephemeral: Some(false),
Secondary symptom: zombie threads can’t be archived
v1 archiveConversation currently requires rolloutPath in params.
If the UI thread object lacks it (because conversation start failed partway), archiveConversation can’t be called.
Proposed fix
Make ArchiveConversationParams.rollout_path optional, and if missing (or if archive fails with provided path), resolve the rollout path from disk via conversationId (find_thread_path_by_id_str) and archive that.
Given the invitation-only PR policy: if this diagnosis/approach matches the intended fix and you’d like me to contribute code, please invite me to open a PR (I already have working patches + tests from the closed PRs). Otherwise I’m happy to keep helping with repro/logs and let the team implement internally.
Update with evidence from Codex Desktop logs: the archive failure seems to be v2 thread/archive, and it fails because the rollout file is missing (not just missing rolloutPath in params).
Examples from my local logs:
2026-02-16T07:17:10.345Z: method=thread/archive -> error {"code":-32600,"message":"no rollout found for thread id 019c640e-0809-7143-8800-57f844c178e2"}
2026-02-15T23:16:10.762Z: method=thread/archive -> error {"code":-32600,"message":"no rollout found for thread id 019c5c94-c4f0-7eb2-82c7-cf3f9bb21d27"}
This matches the symptom “zombie thread can’t be archived”: the thread exists in the UI but has no rollout materialized on disk.
Possible fix direction: make thread/archive succeed even when no rollout exists (e.g. treat as empty/unmaterialized thread and remove/mark-archived in state DB + shutdown/remove from thread manager), or create a minimal stub rollout file at the expected path and then archive it.
I suspect this no-client-found is what ultimately surfaces as the generic UI toast “Error starting conversation”, and it also explains why “zombie threads” get created: the thread gets created locally, but the first turn never successfully submits / rollout never materializes.
If helpful I can capture a /feedback bundle immediately after repro and share exact mic HW details + whether typed messages still work while the external mic is selected.
Immediately after that, the desktop logs show no-client-found:
2026-02-17T01:31:16.836Z error [electron-message-handler] Error creating local task errorMessage=no-client-found ...
So far this points to a client/context initialization path failing (likely gated by voice/transcribe flow and possibly input device selection), rather than the model/network call failing.
Root cause: v1 conversation handlers (process_new_conversation, handle_resume_conversation, handle_fork_conversation) build ConfigOverrides with ephemeral: None, so ephemeral = true from config.toml leaks through. v1 doesn't support ephemeral threads, rollout_path comes back None, error fires — but the thread is already created. Zombie.
Second problem: v2 thread/archive hard-fails with "no rollout found" when the rollout was never materialized, so these zombies can't be cleaned up.
Fix:
Set ephemeral: Some(false) explicitly in all v1 ConfigOverrides
When v1 handlers hit None rollout_path anyway, shut down and remove the thread before returning the error
In v2 thread/archive, when find_thread_path_by_id_str returns Ok(None), clean up the thread and return success instead of erroring
Tested locally against the full app-server suite (193 pass, 0 fail). Can share patches if the team wants to pick this up.
Activity
twentyOne2x commentedon Feb 16, 2026
Opened PR #11905 to make v1 work even when is missing/null by resolving the rollout from . This should address the stuck/zombie threads being unarchivable (even if the underlying conversation-start error persists).
twentyOne2x commentedon Feb 16, 2026
Follow-up (previous comment got mangled by shell backticks): Opened PR #11905 to make v1
archiveConversationwork even whenrolloutPathis missing/null by resolving the rollout path fromconversationId. This should address the stuck/zombie threads being unarchivable (even if the underlying conversation-start error persists).twentyOne2x commentedon Feb 16, 2026
Additional context: I’m on the Pro plan (if that matters for model access/rate limits).
twentyOne2x commentedon Feb 16, 2026
PR up: #11910
This should address the instant “Error starting conversation” path when the v1
newConversationflow ends up starting an ephemeral session (norolloutPath), which then errors while responding and leaves a zombie thread in the UI.twentyOne2x commentedon Feb 16, 2026
If you can repro this, can you run the command in Codex to upload logs/session data and then post the thread ID(s) here? Also helpful: the exact Codex macOS app version string from About Codex + your macOS version.
twentyOne2x commentedon Feb 16, 2026
Follow-up: if you can repro this, please run the /feedback slash command in Codex to upload logs/session data and then post the thread ID(s) here. Also helpful: the exact Codex macOS app version string from About Codex + your macOS version.
twentyOne2x commentedon Feb 16, 2026
Heads-up: both PRs (#11905 / #11910) were closed due to the invitation-only contribution policy (see discussions/9956). No worries — here’s the distilled analysis + patch sketch in case the team wants to implement internally.
rolloutPath.ephemeral=trueis set via params.config (or via a profile), Codex intentionally producesSessionConfiguredEvent.rollout_path = None.Proposed fix (minimal / defensive)
ephemeral=falsefor v1 conversation start/resume/fork by settingConfigOverrides.ephemeral = Some(false)in the v1 handlers.config: { ephemeral: true }and assert it still returns an absolute rolloutPath.Code sketch (from closed PR #11910):
process_new_conversation,handle_resume_conversation,handle_fork_conversation:ephemeral: Some(false),rolloutPathin params.Proposed fix
ArchiveConversationParams.rollout_pathoptional, and if missing (or if archive fails with provided path), resolve the rollout path from disk viaconversationId(find_thread_path_by_id_str) and archive that.Code sketch (from closed PR #11905):
pub rollout_path: Option<PathBuf>archive_conversation(...):If it helps, I can also paste the exact diffs / tests from those PRs here.
twentyOne2x commentedon Feb 17, 2026
Given the invitation-only PR policy: if this diagnosis/approach matches the intended fix and you’d like me to contribute code, please invite me to open a PR (I already have working patches + tests from the closed PRs). Otherwise I’m happy to keep helping with repro/logs and let the team implement internally.
twentyOne2x commentedon Feb 17, 2026
Update with evidence from Codex Desktop logs: the archive failure seems to be v2
thread/archive, and it fails because the rollout file is missing (not just missing rolloutPath in params).Examples from my local logs:
method=thread/archive-> error {"code":-32600,"message":"no rollout found for thread id 019c640e-0809-7143-8800-57f844c178e2"}method=thread/archive-> error {"code":-32600,"message":"no rollout found for thread id 019c5c94-c4f0-7eb2-82c7-cf3f9bb21d27"}This matches the symptom “zombie thread can’t be archived”: the thread exists in the UI but has no rollout materialized on disk.
Possible fix direction: make
thread/archivesucceed even when no rollout exists (e.g. treat as empty/unmaterialized thread and remove/mark-archived in state DB + shutdown/remove from thread manager), or create a minimal stub rollout file at the expected path and then archive it.twentyOne2x commentedon Feb 17, 2026
New repro detail: the failure seems input-device-dependent.
thread/start/turn/startfailure):I suspect this
no-client-foundis what ultimately surfaces as the generic UI toast “Error starting conversation”, and it also explains why “zombie threads” get created: the thread gets created locally, but the first turn never successfully submits / rollout never materializes.If helpful I can capture a
/feedbackbundle immediately after repro and share exact mic HW details + whether typed messages still work while the external mic is selected.twentyOne2x commentedon Feb 17, 2026
Extra datapoints:
thread/start/turn/startfailure).turn/startin logs:019c6939-1d13-7592-81e1-6bffaa99cef1(created2026-02-17T01:31:16Z)no-client-found:So far this points to a client/context initialization path failing (likely gated by voice/transcribe flow and possibly input device selection), rather than the model/network call failing.
cschar commentedon Feb 21, 2026
I have this issue as well
aeplay commentedon Feb 24, 2026
if it helps, I get no-client-found very frequently on thread creation, and I never use transcription.
Also on MacOS. Restarting the app temporarily fixes the issue.
shouryamaanjain commentedon Feb 25, 2026
Root cause: v1 conversation handlers (
process_new_conversation,handle_resume_conversation,handle_fork_conversation) buildConfigOverrideswithephemeral: None, soephemeral = truefromconfig.tomlleaks through. v1 doesn't support ephemeral threads,rollout_pathcomes backNone, error fires — but the thread is already created. Zombie.Second problem: v2
thread/archivehard-fails with "no rollout found" when the rollout was never materialized, so these zombies can't be cleaned up.Fix:
ephemeral: Some(false)explicitly in all v1ConfigOverridesNonerollout_path anyway, shut down and remove the thread before returning the errorthread/archive, whenfind_thread_path_by_id_strreturnsOk(None), clean up the thread and return success instead of erroringTested locally against the full app-server suite (193 pass, 0 fail). Can share patches if the team wants to pick this up.