Skip to content

Codex desktop (Windows): follow-up messages in existing threads never send #45069

Description

@I-shang-I

What version of the Codex App are you using (From “About Codex” dialog)?

26.908.40834

What subscription do you have?

Pro

What platform is your computer?

Windows 11 Home, build 26200 (x64); the machine is behind a TLS-inspecting proxy, but the proxy is not involved

What issue are you seeing?

Symptoms

  1. A new chat's first message sends normally. Every later message in that thread, and any message in an existing thread, spins forever. The text stays in the composer.
  2. No request reaches the app-server. The desktop logs show no turn/start, turn/steer or thread/queue/add, and no error.
  3. Sending to the same thread from the ChatGPT mobile app (remote control) works.
  4. Sending through the in-app send_message_to_thread tool also works.
  5. None of these helped: restarting the app, re-login, clearing the Electron Cache, Code Cache and GPUCache, switching followUpQueueMode between queue and steer, changing the model or permission mode, or using a different project folder.

Root cause analysis (runtime evidence)

The app was launched inside its package with --remote-debugging-port bound to 127.0.0.1. Non-pausing logpoints were set in webview/assets/app-primary-17b54400f32a.js and app-initial-d9bed9d614d8.js. The minified names below are from this build.

  1. The composer submit gate parks the message. At the start of Evr's submit handler the state was {submitDisabled:false, submitting:false, submitBlockReason:"loading-local-config"}. yvr.queueSubmit then queued it with isLocalConfigPending:true. None of the later steps ran (cvr, the turn coordinator, turn/start).

  2. Why isLocalConfigPending is true. Ygr() ends with composerMode==='local' && (localWorkspaceMaterialization==='loading' || …). The submit block context was:

    agentMode: guardian-approvals, isAgentModeLoading: false, isAgentModePending: false,
    windowsSandboxRequirement: null, isWindowsSandboxRequirementPending: false,
    localWorkspaceMaterialization: "loading", composerMode: "local", roots: ["D:\\Claude\\Kova"]
    

    Every other input was ready. The config/read, host and cwd data used by pvr() were all cached.

  3. Why materialization is loading. The D8 query options (managed-worktree-state) read TC = ["vscode","codex-home",{hostId}]. Because TC has no data and no error, D8 returns a disabled query keyed codex-home-loading. aQo then maps "no data" to "loading" indefinitely. Live query cache:

    ["vscode","codex-home","{\"hostId\":\"local\"}"]  status=pending fetchStatus=fetching fetchFailureCount=0 error=null
    ["vscode","codex-home"]                          status=pending fetchStatus=fetching fetchFailureCount=0 error=null
    ["git","local","managed-worktree-state","codex-home-loading","D:\\Claude\\Kova"]  status=pending fetchStatus=idle
    
  4. The startup codex-home request is never answered.

    • The renderer fetch client (sS.getInstance(), the vscode://codex/* bridge) still held 11 unresolved entries in pendingRequests about 30 minutes after launch.
    • The main process logged [electron-fetch-handler] codex-home request only during startup (six lines between +1.1 s and +14 s).
    • A fresh post('vscode://codex/codex-home', {"hostId":"local"}) from the same renderer returned in 2 ms with {"codexHome":"C:\\Users\\User\\.codex","worktreesSegment":"C:\\Users\\User\\.codex\\worktrees"}. The main handler (readCodexHomePaths) itself works; only the startup requests are lost.
  5. Why it never recovers. TanStack Query's Query.fetch reuses the in-flight retryer when state.data === undefined, even with cancelRefetch: true. Invalidation and refetch therefore keep waiting on the lost promise. There is no timeout on the bridge request.

  6. Confirmation. Running queryClient.cancelQueries({predicate: codex-home}) and then refetchQueries(...) turned both queries to success. D8 switched to ["git","local","managed-worktree-state","available",...], and the next desktop submit in an existing thread sent turn/start successfully (2026-09-12T15:48:34Z, conversation 01a0959a-…). This was the first one since 2026-09-11 16:18.

Startup timing correlation (not proven causal)

Times are milliseconds after Launching app:

Launch Result First codex-home requests First query-cache-invalidate broadcast
2026-09-09 works +3537, +3542 none in the first 40 s
2026-09-11 14:01 (d61b04e1) works +8872, +8905 +23185 (after avatar overlay loaded)
2026-09-11 16:35 (bbafcf82) fails +5219, +5237 +8568
2026-09-12 21:15 (430813af) fails +2565, +2573 +2893
2026-09-12 23:13 (4c766004) fails +2395, +2407 +3389

In every failing launch, an IPC query-cache-invalidate broadcast arrives about 1 s after the main window's first codex-home requests. It shows up in the main log as [IpcClient] Received broadcast but no handler is configured method=query-cache-invalidate. In the working launches it arrives much later or not at all during startup. This may be how responses get lost or mis-routed, but it has not been proven.

Ruled out

  • App-server: healthy. One codex.exe, fast responses, no queued items, SQLite quick_check ok.
  • Stream ownership and resume: the thread was resumed and this window was the owner.
  • Other submit gates: the goals feature (no goals), Windows sandbox readiness, and agent-mode or model-settings loading were all ready.
  • Remote-workspace gate: it would show a dialog, not a spinner.
  • Thread cwd: the \\?\ prefix and the specific project folder make no difference.
  • Machine environment: WSL (healthy), proxy or TLS, stale helper processes, OS updates.

What steps can reproduce the bug?

Feedback ID: 01a0959a-8824-7282-9ac2-59173f451f2d

What is the expected behavior?

Able to submit prompt to the previous session.

Additional information

Suggested fixes

  1. Add a timeout and retry to vscode://codex/* bridge requests, or reject pending requests on any window or IPC reset. Unanswered bridge requests should never hang forever.
  2. For codex-home, handle a stuck initial fetch with no data: cancel it, then refetch, instead of relying on cancelRefetch.
  3. Do not block the composer indefinitely when localWorkspaceMaterialization is loading. Fail open or show an actionable error after a timeout.
  4. Log bridge requests that stay pending longer than N seconds, with their URL, so this is visible in the desktop logs.

Workaround in use

Launch Codex with --remote-debugging-port=<port> via Invoke-CommandInDesktopPackage, then cancel and refetch the stuck codex-home queries through DevTools. This lasts only for that app session.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    appIssues related to the Codex desktop appapp-serverIssues involving app server protocol or interfacesbugSomething isn't workingwindows-osIssues related to Codex on Windows systems

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions