Voice chat fails to start: overlay 10s launch timeout races slow skills/list; session starts after timeout fires
Summary
Voice chat in the Codex desktop app reliably fails with "Voice chat couldn't start — Voice chat took too long to start" whenever skills/list takes more than a few seconds. The realtime session itself actually starts — but ~1s after the overlay's hard-coded 10s launch timeout (cue=1e4 in app.asar) has already fired and torn the session down.
Environment
- macOS 15.7.3 (arm64), Codex desktop build 26.721.81911, codex-cli 0.146.0-alpha.3.1
- ~190 user/plugin skills on disk (~25 plugins enabled)
What happens (from ~/Library/Logs/com.openai.codex/...)
A single voice click produces three sequential skills/list calls in the avatar overlay's startup path, each taking 4–10s inside the app-server:
13:28:01.091 Skills/list request (avatarOverlay)
13:28:08.161 response_routed method=skills/list durationMs=5857 queueWaitMs=1213
13:28:08.745 Skills/list request (again)
13:28:11.786 [avatar-overlay-realtime] Voice chat took too long to start <- 10s timeout fires
13:28:13.544 response_routed method=skills/list durationMs=4003
13:28:16.660 Skills/list request (third time)
13:28:20.399 Conversation created ... Archive requested source=realtime_voice_provisional
13:28:23.975 response_routed method=skills/list durationMs=6628
In an earlier attempt the log shows realtime_session_started at 11:10:44.210 — 0.9s after the timeout error at 11:10:43.322. The backend was ready; the UI gave up too early.
Root cause (measured)
skills/list cost is dominated by the skill-root directory walk:
- The walker is a fully sequential async BFS paying multiple
tokio::fsround trips per directory entry (file-system/src/lib.rswalk_via_directory_reads,exec-server/src/local_file_system.rs). With a large directory inside a skill root (in my case a 6,500-file git repo withnode_modulesunder~/.codex/skills/), oneskills/listgenerates ~120,000 tracing span entries and takes 4–11s. Moving that directory out of the skill root drops span count to ~35k and standalone latency to 0.4s. effective_skill_roots_for_layer_stackruns a full uncached plugin enumeration on every call, even whenforceReload=falseand the per-cwd snapshot cache would hit (catalog_processor.rs), so the per-call floor stays high.- The overlay calls
skills/listthree times per voice attempt, serialized against a ~10s launch budget. - The launch timeout is a hard-coded constant (
cue=1e4), not configurable and not tied to actual readiness.
Note: with a busy app-server (thread hydration, MCP startups, remote-control enrollment), in-app skills/list remains 4–6.6s even after the on-disk fix above, so the 10s budget is still exceeded. A standalone app-server answers the identical request in 0.4–1.5s.
Expected
- Voice startup should not be gated on a complete skills enumeration (or the launch timeout should be generous/configurable, e.g. 30–60s).
- The session that successfully started should be attached instead of discarded when the timeout races it.
Suggestions
- Don't block
thread/realtime/startreadiness onskills/list(load skills lazily in the overlay), and/or deduplicate the three calls per attempt. - Cache plugin skill roots between
skills/listcalls. - Parallelize/batch the directory walk (metadata per entry is currently awaited one-by-one).
- Make the launch timeout configurable or increase it; on timeout, check whether the session actually started before tearing down.
Related
- #35490 (Cloudflare 403 on realtime endpoints) — distinct issue; that one is an upstream/network block, this one is a local startup-latency race. With #35490 not reproducing, voice still fails purely due to this timeout.
1 Comment
Still reproducing consistently on Windows with Codex App 26.818.5229.0.
Platform:
Microsoft Windows NT 10.0.28120.0 x64Voice was started from a new, empty task inside an existing project, before sending any text message. The Windows microphone permission for
OpenAI.Codexis set toAllow, Windows records recent microphone use, andthread/realtime/listVoicescompletes without an error.The desktop logs show the voice startup watchdog firing before the provisional thread finishes being created:
The same ordering occurs on another attempt:
Immediately before the timeout, the logs contain repeated
bundled_executable_relocation_failedwarnings while copyingcodex.exeand thecua_noderuntime from WindowsApps into the local Codex runtime directory. This may be another source of startup delay that races the overlay watchdog.The issue also reproduced earlier on app version 26.814.5517.0, before updating to 26.818.5229.0.
Feedback ID (logs included):
no-active-thread-01a028f1-0a7d-7510-baba-15e4ae99782e