Skip to content

[Windows Desktop][26.803.10989.0] Six stuck app-server requests freeze every window and remove Fast mode #38385

Open

Description

@keepyourpolicy-lab

What version of the Codex App are you using (from the About dialog)?

OpenAI Codex Windows package 26.803.10989.0 (x64), bundled backend codex-cli 0.147.0-alpha.6.6.

What subscription do you have?

ChatGPT sign-in. Exact plan is omitted because the failure occurs in the local Desktop/app-server transport before a model turn starts.

What platform is your computer?

Windows 11 Pro 25H2, build 26200.9168, x64.

What issue are you seeing?

All open Codex Desktop windows intermittently stop receiving app-server data at the same time. Existing tasks stop updating, new sends time out, and model/config-dependent UI stops populating. In particular, Speed -> Fast disappears from the model menu. Fully quitting and restarting Codex immediately restores every window and makes Fast selectable again under the same account.

This reproduced twice on 2026-08-13. Sanitized renderer-log evidence from the two independent app sessions:

Incident 1
11:42:06Z config/read rejected after queue expiry, inFlightRequestCount=6
11:42:08Z model/list rejected after queue expiry
11:42:13Z critical turn/start timed out
11:43:39Z another turn/start timed out

Incident 2
13:30:55Z model/list rejected after queue expiry, inFlightRequestCount=5
shortly afterward inFlightRequestCount reached 6
plugin/list, skills/list, and thread/list then expired while queued
13:32:20Z critical turn/start timed out

Representative sanitized signature:

app_server_client_request_queue_rejected
method=config/read
priority=critical
inFlightRequestCount=6
reason=queue-expired

mcp_request_timeout method=turn/start timeoutMs=30000

The Fast-menu symptom appears to be downstream, not an entitlement change: model/list and config/read cannot cross the saturated local queue, and a restart restores the option without any account change.

Both incidents occurred while the same collaboration-heavy task was coordinating multiple subagents. A structural-only trace (no task text or identifiers) shows:

Incident 1: spawn_agent at 11:41:07Z -> no parent-task events during the stall -> activity resumes after restart
Incident 2: spawn_agent at 13:29:32Z, wait_agent at 13:29:38Z -> model/list expires at 13:30:55Z -> turn/start times out at 13:32:20Z -> activity resumes after restart

This makes subagent/collaboration concurrency a likely trigger or amplifier, but does not prove that a particular subagent request is the original hung request.

There was also an unusually large untracked dependency backup in the working tree during the first incident: 20,249 files and approximately 3.1 million added lines entered a turn snapshot, with one emitted diff event around 59 MB. Excluding that already-preserved directory from local Git enumeration reduced the untracked snapshot surface to 307 files. That load may help trigger the stall, but it does not explain why already-dispatched requests retain all six scheduler slots indefinitely.

Installed-bundle diagnosis

Inspection of the installed, version-specific Desktop JavaScript bundle suggests the following failure path:

  • One app-wide scheduler is shared by all windows and has a maximum of six dispatched requests (the installed minified bundle uses eU=6; the background threshold is tU=5).
  • Once six requests have been marked sentToTransport, getNextRequestIndex stops dispatching anything else.
  • The renderer's 30-second MCP timeout rejects the caller, but does not appear to cancel or remove an already-dispatched scheduler entry.
  • dropUnsentRequest removes only requests that have not yet been sent to the transport.
  • If six dispatched app-server calls never complete, the queue remains permanently full. Later model/list, config/read, thread/list, plugin/skill discovery, and even critical turn/start calls queue and expire.

That model matches both observed sessions and explains why every Desktop window fails together and why a full restart is curative.

What steps can reproduce the bug?

The trigger is intermittent, but it reproduced twice within about two hours with this pattern:

  1. Open multiple Codex Desktop windows.
  2. Keep a collaboration-heavy task active and coordinate multiple subagents using repeated spawn, follow-up, message, and wait operations.
  3. Continue switching tasks or sending work from other windows. A very large working-tree snapshot was present in one observed incident.
  4. When six dispatched app-server requests stop completing, observe that every window stops updating and later requests expire.
  5. Open the model menu: Fast is missing because model/config metadata cannot load.
  6. Fully quit and restart Codex Desktop. Windows resume and Fast reappears immediately.

I do not yet have a deterministic minimal reproducer.

What is the expected behavior?

  • A dispatched app-server request needs a bounded watchdog/cancellation path that always releases its scheduler slot.
  • If the child app-server or transport stops completing requests, Desktop should recycle that connection/process automatically rather than leave six permanent in-flight entries.
  • Critical turn/start, config/read, and model metadata traffic should not starve behind background collaboration/history work.
  • A failure initiated by one task must not disable every window that shares the Desktop backend.
  • The UI should preferably retain last-known model/speed metadata while a refresh is temporarily unavailable, rather than making Fast appear to have been revoked.

Additional information

  • savedRemoteConnectionCount=0; this is not the unavailable-SSH-host path described in Desktop auto-connects discovered SSH hosts at startup and blocks local chat loading when a host is unavailable #35733.
  • The machine was not under system memory pressure during either incident.
  • There was exactly one official packaged Desktop root and one packaged child app-server. Separate VS Code and task-specific app-server processes were present but had different parents and executable locations.
  • No raw logs or screenshots are attached because they contain task names, local paths, and conversation identifiers. Targeted redacted excerpts can be provided if maintainers request them.
  • Temporary local workaround: restart Codex Desktop. A conservative local watchdog now detects only the exact six-slot-plus-turn/start signature and restarts the packaged child app-server, with a full packaged-app restart only as fallback.

Possibly related, but not exact duplicates: #36914 (collaboration hydration starvation), #23644 (stale conversation state and six-slot queue expiry), #27395 (sidecar stalls and turn/start timeouts), #37775 (active Windows turns stop showing progress), and #35782 (Windows app-server recovery under concurrent tasks).

Activity

  1. added
    bugSomething isn't working
    appIssues related to the Codex desktop app
    windows-osIssues related to Codex on Windows systems
    app-serverIssues involving app server protocol or interfaces
    subagentIssues involving subagents or multi-agent features
    on Aug 13, 2026
  2. github-actions commented on Aug 13, 2026

    @github-actions
    Contributor

    Potential duplicates detected. Please review them and close your issue if it is a duplicate.

    Powered by Codex Action

  3. Jackten commented on Sep 5, 2026

    @Jackten

    Confirming the same six-slot queue-starvation signature on macOS Codex Desktop, with a model-picker consequence.

    Environment:

    • Codex Desktop 26.901.41123 (build 7942)
    • Bundled CLI/app-server 0.153.3
    • Host: Darwin 25.5.0 arm64 arm
    • ChatGPT Pro

    Sanitized log sequence from 2026-09-05:

    app_server_client_request_queue_rejected inFlightRequestCount=6 method=experimentalFeature/list reason=queue-expired queueWaitMs=3993
    app_server_client_request_queue_rejected inFlightRequestCount=6 method=model/list reason=queue-expired queueWaitMs=3995
    mcp_request_timeout method=model/list timeoutMs=3995
    

    The model picker intermittently omitted GPT-6 Astra during this condition. This was not an entitlement/catalog issue:

    • models_cache.json contained gpt-6-astra.
    • A later direct model/list against the persistent official app-server returned Astra successfully under the same account.
    • No account or entitlement change occurred between failure and success.

    In a nearby app session, plugin/list repeatedly timed out at 30 seconds and later failed while queued. That is a possible trigger/amplifier, but I do not yet have enough evidence to say which dispatched request originally retained the slots.

    This adds a macOS reproduction to the existing Windows report and shows that unavailable model metadata can make a specific model appear revoked even though the catalog and account still permit it. Retaining the last-known model list in the picker would reduce the misleading UI impact, but the underlying need is still cancellation/recovery that reliably releases dispatched scheduler slots.

  4. san1yus commented on Sep 7, 2026

    @san1yus

    Additional reproduction on Windows Desktop package 26.901.6511.0, using backend 0.153.4.

    The same failure pattern occurred in three separate app sessions: all task views remained refreshing, and six requests that had reached the backend had no matching routed response before the app was closed. The outstanding request types varied across sessions and included account, configuration, and task metadata reads. Later requests expired in the desktop queue with inFlightRequestCount=6. Restarting the app restored operation.

    A standalone fake-clock test of this installed build's scheduler reproduced the failure to release capacity:

    1. Dispatch six requests and mark them sent to the transport.
    2. Deliberately withhold their responses in a fake transport.
    3. Enqueue a critical turn/start request.
    4. Advance the fake clock past the request deadlines.
    5. The critical request expires without being dispatched, while the six sent requests continue occupying all slots.
    6. Attempting to remove the sent requests through dropUnsentRequest returns false. Completing one request immediately allows another to dispatch.

    The installed scheduler clears the queue-expiration timer at dispatch. Queue expiry handles queued requests only. This test establishes a recovery failure in the scheduler; it does not reproduce or identify the initial backend hang.

    Suggested acceptance criteria:

    • Dispatched requests have appropriate bounded execution deadlines, separate from queue-wait deadlines.
    • Expired requests produce an explicit recoverable UI state rather than indefinite refreshing.
    • Cancellation failure and an unresponsive backend trigger connection recovery, with late responses from the previous connection generation ignored.
    • Recovery reconciles task state and preserves drafts, without automatically replaying mutations whose outcome is unknown.
    • A six-nonresponding-request regression test also verifies that a healthy replacement connection can service metadata reads.

    Current configuration parsing, database integrity checks, HTTP reachability, and a WebSocket handshake passed after restart. Those healthy-session checks do not rule out a transient failure during the stalls.

  5. ato4040 commented on Sep 8, 2026

    @ato4040

    Additional Windows reproduction with a longer independent monitoring window and late-response evidence.

    Environment:

    • Codex Desktop 26.901.6511.0
    • Bundled CLI/app-server 0.153.4
    • Windows 11 x64

    Observed evidence:

    • A completed 24-hour external watcher run captured 2,882 samples, 1,101 six-slot queue-expiry events, 116 desktop/app-server bridge timeouts, and 4 natural Desktop restart boundaries. These are event counts, not 1,101 independent freezes.
    • In a later Sep 8 incident window, the same build produced another 715 six-slot queue-expiry events and 40 request timeouts.
    • Most importantly, 35 requests that had already timed out in the Desktop/frontend later received successful backend responses. The longest observed late success arrived about 354 seconds after the frontend timeout.
    • This means a Desktop timeout does not reliably mean “not executed.” Blindly retrying write-capable operations can therefore create duplicate side effects unless the client first reconciles the original request outcome.
    • Fully restarting Desktop again cleared the saturated generation and restored operation temporarily. No relevant GPU/hardware error was found in that particular queue-stall window.

    Local mitigations had already reduced nonessential MCP/helper fan-out and default task concurrency, but the six-slot starvation still recurred. That does not prove MCP retention is unrelated; it does show that those mitigations are not a root fix for the shared request-lifecycle failure.

    The strongest product-level requirement from this newer evidence is safe handling of “sent, caller timed out, outcome unknown” requests:

    1. Do not treat caller timeout as proof the request was not executed.
    2. Preserve request identity/outcome reconciliation so late responses can be matched safely.
    3. Avoid blind automatic replay of mutating requests after recovery.
    4. Recover or replace an unhealthy connection generation before all six shared slots permanently block foreground control traffic.
    5. Surface an explicit “outcome unknown / reconciling” state instead of only App server request expired while queued.

    This report intentionally omits local paths, project names, thread/conversation IDs, request IDs, credentials and task contents.

  6. ato4040 commented on Sep 9, 2026

    @ato4040

    Additional recurrence from an independently monitored Windows Desktop session on 2026-09-09 (UTC+8). This is another Desktop-path incident; the affected long-running tasks had not yet been moved to the independently validated CLI execution path.

    Sanitized timeline:

    • 01:56 local: 3 frontend/request timeouts.
    • 02:00 local: 2 six-slot queue-expiry events; the independent guard entered RED_QUEUE.
    • 07:39:24–07:40:10 local: another 19 queue-expired events, all with inFlightRequestCount=6.
    • 07:40:43 local: a new Desktop process generation appeared, matching a user-initiated app restart.

    Resource/process boundary around that restart:

    • Before restart: approximately 370 Desktop/app-server descendants and 11.88 GiB private memory in the observed Codex process tree.
    • After restart: approximately 17 descendants and 2.41 GiB private memory.

    The selected Windows event checks did not show a contemporaneous GPU reset, hardware, disk, or application-crash event in this queue-stall window. That does not exclude every system factor, but there was no matching selected OS fault that explains this recurrence.

    Monitoring limitation: the guard's maximum sample gap in this interval was about 46 seconds. It reliably captured the explicit queue errors, but it cannot prove that the app was continuously stalled from 02:00 through 07:40 if a silent period emitted no diagnostic lines.

    One operational clarification from this incident: loading reliability/CLI-first instructions inside a Desktop task is not equivalent to moving that task onto an independent CLI process. The affected tasks were still executing through the Desktop/app-server path, so this recurrence should not be interpreted as evidence that the CLI isolation workaround itself failed.

    No task contents, project names, local paths, thread/request IDs, credentials, or account identifiers are included here. No processes were killed and no system/MCP settings were changed while capturing this incident.

    Taken together with the earlier late-response evidence, the practical requirement remains bounded recovery and safe outcome reconciliation for already-dispatched requests, rather than treating a frontend timeout as proof of non-execution.

  7. dmncklnr commented on Sep 25, 2026

    @dmncklnr

    Additional Mac-to-Mac case on 26.917.71314: remote sends stuck for roughly 44 minutes

    This is a new and disruptive problem for me. Messages sent from the desktop app on my MacBook to a task running on my Mac mini can remain stuck for minutes, sometimes over half an hour, and sometimes never arrive. I had to use Apple Remote Desktop to send the latest message directly in the app on the mini.

    I am adding this evidence here because the controller logs repeatedly show the same inFlightRequestCount=6 queue-expiry signature. Remote Control sequence-gap failures also occur, as reported in #32241. A shared root cause is not yet established.

    Environment

    • Controller: MacBook, macOS 15.8, arm64.
    • Host: Mac mini, macOS 26.6.2, arm64.
    • Both desktop apps: 26.917.71314, build 10954.
    • Both bundled runtimes: codex-cli 0.155.0-alpha.16.4.
    • Connection: desktop-to-desktop Remote Control.
    • One main bundled app-server under each desktop app was found during the audit.

    Latest incident — 25 September 2026, UTC

    Time Observation
    11:38:28.333 Previous run in the affected task completed on the mini.
    11:43:43.021 MacBook rejects a critical configRequirements/read after 30 seconds queued, with six requests in flight.
    11:43:43.025 MacBook logs turn-start configuration preparation for the affected task. This is not a delivery acknowledgement.
    11:44:13.026 model/list expires while queued; six requests remain in flight and one critical request is queued.
    11:44:18.706–12:26:29.032 Repeated configuration/model queue expiries and remote catalog errors continue.
    Approximately 12:27:07–12:27:20 MacBook desktop app quits and relaunches.
    12:27:11.838 Sending directly in the mini's app succeeds: turn/start acknowledgement in 16 ms, queueWaitMs=0, errorCode=null.
    12:27:11.917 Mini's canonical task transcript records the direct user message. No intervening user message was accepted after the previous run completed.
    12:28:42.760 MacBook thread/resume succeeds in about 140 ms after relaunch.

    There are about 43 minutes 29 seconds between the MacBook's failed send-preparation sequence and acceptance of the direct message on the mini. The initial click time is not logged. The previous run was already complete, so this was not a follow-up waiting for an active run. The 16 ms figure is the local turn-start RPC acknowledgement, not model generation time.

    Sanitized diagnostic fields

    Selected fields from the MacBook log:

    2026-09-25T11:43:43.021Z
    app_server_client_request_queue_rejected
    method=configRequirements/read priority=critical
    inFlightRequestCount=6 queueWaitMs=30002 reason=queue-expired
    
    2026-09-25T11:44:13.026Z
    app_server_client_request_queue_rejected
    method=model/list
    inFlightRequestCount=6 queuedCriticalRequestCount=1
    queueWaitMs=30000 reason=queue-expired
    
    2026-09-25T11:44:18.706Z
    Thread catalog sync failed
    App server catalog request expired while queued
    

    The mini's successful direct submission:

    2026-09-25T12:27:11.838Z
    response_routed
    method=turn/start durationMs=16 queueWaitMs=0 errorCode=null
    

    Earlier that day, the affected task also had an explicit failed send:

    2026-09-25T08:11:01.404Z
    remote control app-server stream sequence gap detected
    
    2026-09-25T08:11:01.469Z
    method=turn/start
    Codex app-server is not available
    

    Sequence-gap disconnects recurred at 09:16, 09:49, and 10:56 UTC. Following the 12:27 app relaunch, the remote connection initially had 85 pending client requests and some queue-full failures before reads began succeeding.

    How this occurs and what remains unknown

    1. Connect the MacBook desktop app to the Mac mini through Remote Control.
    2. Open an existing task on the mini and send the next instruction after its previous run has completed.
    3. Intermittently, the MacBook remains stuck and the new instruction does not appear in the mini's canonical task history.
    4. Access the mini through Apple Remote Desktop and send directly; the mini accepts the message promptly.
    5. Restarting the controller can restore access, but the failures recur.

    I do not have a deterministic minimal reproducer. The logs do not identify which six requests held capacity, prove that every sequence gap causes the long stall, or establish the exact network/relay/client fault.

    A configuration comparison found no changed provider or remote-connection settings. A matching sequence-gap error also appears on the preceding day. That does not establish when the user-visible sending problem began; it has only recently become disruptive for me.

    Requested outcome

    Please investigate bounded recovery of the desktop remote request queue and safe handling of pending sends after reconnect. A failed send should produce a clear recoverable state, preserve the draft, and reconcile whether the host received it before allowing a retry to duplicate the instruction.

    Please identify a fixed desktop build, if one exists, or a supported recovery procedure that preserves active host work. Repeated manual restarts and using Remote Desktop just to submit a message are not a workable long-term solution.

    This comment contains selected diagnostic fields only. Raw logs, private task content, local paths, account/device identifiers, and task/request IDs are omitted. No in-app Feedback ID was generated.

  8. light-merlin-dark commented on Sep 27, 2026

    @light-merlin-dark

    One concrete way into the six-slot starvation on macOS Codex Desktop: a response lost to a stdout JSONL parse failure never releases its in-flight slot.

    Environment: Codex Desktop 26.924.22138 (build 11645), bundled codex-cli 0.158.0-alpha.2.1, macOS Darwin 25.6.0 arm64.

    Sequence on 2026-09-27 (UTC, sanitized):

    20:33:34Z [StdioConnection] Failed to parse app-server stdout JSONL message
              "Expected ',' or '}' after property value in JSON at position 65387" lineBytes=65846
    ... 140 such failures in 90 minutes; none on any earlier day
    21:08:09Z app_server_client_request_queue_rejected inFlightRequestCount=6 method=config/read reason=queue-expired
    21:58:51Z app_server_client_request_queue_rejected inFlightRequestCount=6 method=thread/list ...
              [WindowContext] Thread catalog sync failed "App server catalog request expired while queued"
    

    What the failures have in common:

    • The failing lines are the default thread/list page (25 threads). preview is the uncapped first user message, and one 12.5 KB prompt put that page at about 66 KB.
    • 131 of 140 failures report a JSON error position between 65,436 and 65,442. lineBytes minus position is a few hundred bytes. In one case lineBytes=131382 at position 65,534, which is two catalog pages joined.
    • So the reader keeps the first ~65,440 bytes of the response (the rest of a 64 KiB read that began ~96 bytes into the previous message), loses the tail including its newline, and continues with the next message on the same line. No orphan fragment is ever reported.
    • The app-server side is correct. Replaying the same thread/list against a snapshot of the state DB returns valid 66 KB and 418 KB lines. This held through Node 22 child_process.spawn (socketpair) with a flowing, paused, or event-loop-blocked reader. The 0.158 stdio writer is a single thread doing write_all.
    • Each lost response keeps its request in flight permanently. After six, every later request (config/read, hooks/list, thread/list, skills/list) expires in the queue, so new sessions cannot sync until the app is restarted.

    Two fixes would each stop the user-visible failure:

    1. Expire or fail in-flight requests that never receive a response, so a lost line costs one request rather than the whole connection.
    2. Bound preview in thread/list. The sidebar does not need the full first message, and keeping pages small avoids the multi-read path entirely.

    The dropped read itself is in the Electron main-process reader. We could not reproduce it outside the app, because run-as-node is fused off.

    By Merlin (rbeckner.com) and his AI agent (Claude Code, Claude Opus 5.5, thinking on: low).

  9. kendo1dan3141-collab commented on Oct 16, 2026

    @kendo1dan3141-collab

    Additional Windows Desktop evidence: build 26.1013.3656.0 (October 16–17, 2026)

    This appears relevant to the shared request-queue symptoms in this issue, but I have not established that it has the same root cause.

    Environment: Windows 11 23H2, build 22631.6199; Codex Desktop 26.1013.3656.0. Optional/local MCP servers are configured. A clean configuration without those servers has not been tested.

    Impact: multiple chats first remain thinking or time out, then the entire desktop UI stops accepting clicks. Ending and relaunching Codex has sometimes left it unusable; a Windows reboot was needed. This has repeatedly interrupted work.

    Selected desktop-log observations (timestamps below are JST):

    • October 16, 23:16:44: inFlightRequestCount=8; 1 critical and 14 interactive requests queued.
    • October 17, 00:32:38: mcpServerStatus/list expired while queued for about 30 seconds; inFlightRequestCount=8; 1 critical and 20 interactive requests queued.
    • October 17, 01:01:12: thread/turns/list expired after about 60 seconds in the queue; inFlightRequestCount=5; 16 interactive requests queued.
    • Other observed responses took approximately 313, 381 and 409 seconds. A later mcpServerStatus/list response took about 170 seconds with queueWaitMs=0.

    The in-flight counts are application queue counters, not proof that that many requests reached the backend: readiness/barrier waits may be included. The later recurrence at a count of 5 also means this is not simply evidence of hitting a global limit of 8.

    Windows Error Reporting additionally recorded two Codex cross-process hangs waiting on Windows Search Manager. WSearch was subsequently disabled as a temporary diagnostic mitigation at 00:25. The queue failures above and user-visible freezes recurred afterward, so Windows Search does not explain all observed incidents. A temporary period of responsive UI did not establish recovery.

    Could maintainers investigate the shared app-server queue/readiness path, how stalled requests are cancelled or recovered, and a safe recovery procedure that preserves chat history? Please advise which bounded diagnostic bundle is useful. I am not asserting the stdout-framing cause discussed in earlier comments, and have not attached raw logs containing private workspace information.

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 workingsubagentIssues involving subagents or multi-agent featureswindows-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