Voice Chat global hotkey repeatedly resumes a stale recent thread and fails with `thread not found`

Open 💬 0 comments Opened Jul 27, 2026 by LU90210

Summary

The Codex Desktop global Voice Chat hotkey can become permanently stuck trying to resume a stale realtime-voice-most-recent-thread. Every invocation briefly shows the Voice avatar overlay, then immediately closes it and reports:

thread not found: <stale-thread-id>

Changing the hotkey and fully restarting the app does not help because the stale recent-thread pointer persists. Removing only the realtime-voice-most-recent-thread persisted atom and restarting fixes the problem immediately; the next hotkey invocation creates a working Voice Chat.

Environment

  • App: ChatGPT desktop / Codex view
  • App version: 26.721.41059 (build 5848)
  • Platform: macOS 26.5, Apple Silicon (M2)
  • Architecture: arm64
  • Date reproduced: 2026-07-27

Symptoms

  • With a bare-modifier Voice Chat hotkey, the failure initially looked like the shortcut was not firing.
  • After changing the Voice Chat hotkey to Command+. or Command+/, the Voice avatar overlay became visible.
  • The overlay disappeared almost immediately and several error toasts appeared.
  • Releasing the keys appeared correlated with the overlay disappearing, but logs showed that startup had already failed because Codex tried to reuse a missing thread.
  • Cmd+Q and reopening the app did not resolve it.

Sanitized logs:

[electron-message-handler] Error starting realtime voice
errorMessage="thread not found: <stale-thread-id>"
rendererWindowAppearance=avatarOverlay

[avatar-overlay-realtime] Failed to start realtime in the avatar overlay
errorCode=-32600
errorMessage="thread not found: <stale-thread-id>"

[electron-message-handler] Request failed
method=thread/settings/update
error={"code":-32600,"message":"thread not found: <stale-thread-id>"}

The persisted global state contained:

{
  "electron-persisted-atom-state": {
    "realtime-voice-most-recent-thread": {
      "conversationId": "<stale-thread-id>",
      "hostId": "local",
      "version": 27
    }
  }
}

In this installation, the stale thread was still represented in the legacy state database and its rollout JSONL still existed, but it was absent from the currently active ~/.codex/sqlite/state_5.sqlite. This suggests that a state migration or database-path transition can leave the recent Voice pointer referencing a thread that the current app-server cannot load.

Recovery that worked

  1. Back up ~/.codex/.codex-global-state.json.
  2. Remove only:
electron-persisted-atom-state.realtime-voice-most-recent-thread
  1. Restart ChatGPT desktop.
  2. Invoke the same Voice Chat hotkey.

Voice Chat then starts normally. No microphone, Accessibility, Input Monitoring, Screen Recording, account, or network change was required.

Expected behavior

When the global Voice Chat hotkey is invoked, Desktop should validate that the cached recent Voice thread is loadable before resuming it.

If thread/read, thread/resume, or thread/settings/update returns -32600 thread not found, Desktop should:

  1. retire/clear the stale recent-thread pointer;
  2. create a new Voice Chat automatically, or show a recoverable action;
  3. avoid repeatedly showing identical error toasts; and
  4. avoid requiring users to manually edit .codex-global-state.json.

A state migration should also reconcile realtime-voice-most-recent-thread with the active thread database.

Actual behavior

The avatar overlay repeatedly attempts the same missing thread on every global hotkey invocation. Restarting and changing the shortcut do not help because the invalid pointer remains persisted. The overlay appears briefly, then closes after the startup error.

Privacy note

The raw thread ID, local project path, transcript content, and screenshot are intentionally omitted. I can provide a Feedback ID or additional sanitized logs if needed.

View original on GitHub ↗