macOS app: voice transcription send fails with 'Error starting conversation' and creates zombie thread

Open 💬 14 comments Opened Feb 16, 2026 by twentyOne2x

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?

  1. Open the Codex macOS app
  2. Start a new thread
  3. Use voice transcription (mic), speak a prompt
  4. Press Send
  5. Observe instant toast Error starting conversation
  6. 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

View original on GitHub ↗

14 Comments

twentyOne2x · 5 months ago

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 · 5 months ago

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).

twentyOne2x · 5 months ago

Additional context: I’m on the Pro plan (if that matters for model access/rate limits).

twentyOne2x · 5 months ago

PR up: #11910

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.

twentyOne2x · 5 months ago

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 · 5 months ago

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 · 5 months ago

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.

1) 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.

Code sketch (from closed PR #11910):

  • codex-rs/app-server/src/codex_message_processor.rs
  • in v1 process_new_conversation, handle_resume_conversation, handle_fork_conversation:

ephemeral: Some(false),

2) 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.

Code sketch (from closed PR #11905):

  • codex-rs/app-server-protocol/src/protocol/v1.rs
  • pub rollout_path: Option<PathBuf>
  • codex-rs/app-server/src/codex_message_processor.rs
  • in archive_conversation(...):
  • try provided rollout_path if present
  • else resolve by conversationId and archive

If it helps, I can also paste the exact diffs / tests from those PRs here.

twentyOne2x · 5 months ago

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 · 5 months ago

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.

twentyOne2x · 5 months ago

New repro detail: the failure seems input-device-dependent.

  • Voice transcription works for me w/ AirPods Pro selected as input, but fails when selecting an external mic.
  • When it fails, the desktop logs show a local exception path (not a JSON-RPC thread/start/turn/start failure):
2026-02-17T01:31:16.836Z error [electron-message-handler] Error creating local task errorMessage=no-client-found ...
2026-02-17T01:32:25.212Z error [electron-message-handler] [Composer] submit failed errorMessage=no-client-found followUp=local mode=local

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.

twentyOne2x · 5 months ago

Extra datapoints:

  • Typed messages still work (so it’s not a general thread/start / turn/start failure).
  • The failed attempt created a thread id that never got a turn/start in logs:
  • 019c6939-1d13-7592-81e1-6bffaa99cef1 (created 2026-02-17T01:31:16Z)
  • 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.

cschar · 4 months ago

I have this issue as well

aeplay · 4 months ago

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 · 4 months ago

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.