Skip to content

[Windows Desktop 26.930] Sent read timeouts retain all 8 host RPC slots; Send/Retry fails until restart #50812

Open

Description

@yfyau

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

  • Desktop app: 26.930.31730, build 12947, production channel (reported by the app's version tool).
  • Windows package: OpenAI.Codex 26.930.3930.0, x64 (verified with Get-AppxPackage).
  • Local app-server reports 0.160.0; native Windows stdio transport.
  • The different app/package/backend version numbers are reported separately, not treated as a version mismatch.

What subscription do you have?

ChatGPT-account session. Subscription tier was not collected for this report; the demonstrated failure is in desktop RPC scheduling before the affected new request can reach model inference.

What platform is your computer?

Microsoft Windows NT 10.0.19045.0
x64

What issue are you seeing?

Codex Desktop intermittently reaches a persistent state where Send shows an error icon, Retry also fails, and fully restarting the app restores messaging. The issue affects conversations across multiple local projects.

The diagnostic error is:

[Composer] submit failed
errorCode=-32001
errorMessage="App server request expired while queued"

Some earlier submissions instead fail with Timeout. The user sees only an error icon and Retry in the reported UI state, without an actionable explanation.

This report adds a current-build, cross-layer timeout reproduction to related queue-starvation reports #43525 and #37401. It verifies a failure-to-recover mechanism, not the initial cause of the backend's missing replies. Please consolidate if these belong to the same engineering issue.

Business / workflow impact

  • Message submission becomes unavailable across otherwise unrelated chats on the same local host, blocking ongoing development and follow-up instructions.
  • Repeated Retry attempts spend time waiting and failing without changing the blocked state.
  • Recovery requires leaving the current workflow and restarting the app. On Windows, the inspected reconnect/reset path closes the stdio backend child, so recovery can also interrupt other active turns and process sessions on that host.
  • The error icon does not explain whether a new message was dispatched or whether shared host capacity is exhausted. This makes recovery and coordination of parallel work difficult.

No financial-loss estimate, confirmed task-data loss, or duplicate execution is claimed. Log counts below count internal RPC failures, not user clicks or lost messages.

Observed frequency and release relationship

In retained logs for October 3 UTC, there were 790 app_server_client_request_queue_rejected entries and six Composer submission failures, including four explicit queued-expiry failures. A further October 4 pre-restart segment had 99 queue rejections.

The user noticed increased failures after recent updates. However, build 12694 already exhibited queue expiry on October 3 before build 12947 started that day. The current build remains affected; this is not proof that build 12947 alone introduced the behavior. No controlled old/new workload comparison was performed.

What steps can reproduce the bug?

A. Original application incident — intermittent, initiating trigger unknown

  1. Use several normal local conversations in the Windows desktop app.
  2. During the affected session, some plugin/configuration reads stop producing matching completion records, while the transport remains open and some other RPC methods still respond.
  3. Send a follow-up message. The composer shows an error icon; logs report a timeout or queued expiry.
  4. Retry. It continues to fail.
  5. Fully quit and reopen Codex. Messaging works again according to the user's observation, consistent with the logged backend teardown and successful reconnection.

This is an observed incident sequence, not a deterministic end-user trigger. Opening the Plugins page, one particular plugin, a particular prompt, or a network change has not been isolated as the trigger in this installation.

B. Deterministic offline reproduction of persistent slot retention

An isolated harness reads the installed bundle's actual scheduler/client-queue classes and renderer timeout methods, then connects them to a fake transport that records dispatches but never replies. It does not modify or call the running app.

  1. Dispatch three distinct background plugin/installed requests.
  2. Invoke the actual renderer timeout method for each. Its real abandonment callback reaches the host client queue.
  3. Assert renderer capacity is zero but three host scheduler slots remain occupied.
  4. Dispatch five distinct critical config/read requests and time them out the same way.
  5. Assert renderer promises/capacity are zero while all eight host slots remain occupied.
  6. Submit two new critical read probes representing Retry. Both expire with -32001; neither reaches the fake transport, and the original eight slots remain occupied.
  7. In a separate control fixture, use three plugin/list requests. Their special abandonment path releases all three host slots.

Result: PASS. The exact standalone script embedded below was executed against the reported installed package before submission. Separate earlier checks also verified that a late response releases a slot and connection-state clearing allows new dispatch.

Limitations: the three-plus-five request counts are a synthetic fixture using observed method types, not a reconstruction of all eight historical occupants. Renderer timeout is invoked directly, Retry queue deadlines are shortened to 5 ms, and logging/tracing callbacks are stubbed. The actual timeout, abandonment and scheduling methods are extracted verbatim. This proves the recovery gap under non-response, not the reason the original backend operation stalled.

What is the expected behavior?

Slow or non-completing reads should have a bounded recovery path without permanently consuming all shared interactive capacity. Retry should either make progress or present a clear recovery action. The app should distinguish queued/not-dispatched requests from sent requests with uncertain outcomes, preserve mutation safety, and clearly disclose any host-wide restart impact.

Additional information

Complete causal chain found in the installed code

  1. The host scheduler has a total in-flight limit of 8. Background work has a three-slot lane, with additional noncritical limits and reserved critical capacity.
  2. When a request is dispatched, pumpQueue clears its queue-expiration timer and puts it in the in-flight map. That timer no longer bounds the dispatched operation.
  3. Renderer onTimeout logs mcp_request_timeout, sends mcp-request-abandon, removes its promise, releases renderer capacity and rejects with Timeout.
  4. Main IPC forwards abandonment to the host connection and cA.abandonDestination.
  5. For an ordinary already-sent window request, dropUnsentRequest returns false. Outside special branches, the host does not call scheduler complete; the pending request and host slot stay until a response or connection teardown. Caller timeout is therefore not transport cancellation or host-slot release.
  6. plugin/installed is particularly relevant: the inventory query explicitly uses background priority and a 30-second timeout, but the special detach/release path applies to plugin/list, not plugin/installed. plugin/installed is also absent from the inspected scheduler coalescing set. Three background calls alone cannot fill all eight slots; subsequent critical reads can consume the remaining capacity.
  7. Once the total reaches eight, getNextRequestIndex blocks even newly queued critical work. expireRequest rejects only the newly queued request; it does not clear old sent requests. Repeating Retry does not resolve the saturation.
  8. In the inspected paths, caller timeout/queue expiry does not transition the connection to a recovery state. The normal-connected UI lacks an unconditional reconnect control.
  9. A real late response calls completion; connection teardown calls failPendingClientRequests and clears scheduler/client state. This explains why restart can restore dispatch.

Important exceptions: thread/resume and plugin/list have special cleanup, and tracked mutation outcome-unknown handling releases the scheduler slot while retaining delivery tracking. Those paths should not be conflated with ordinary sent-read retention. This is not a claim of a general memory leak or a proven mutex deadlock.

Composer has blocking critical configuration dependencies, including local-config prefetch and a projectless prepareStart path with a 30-second config/read prerequisite. There is also an optional 500 ms config read that catches the UI error but can leave the host's sent slot retained. The historical IDs have not been mapped to every individual caller, and these distinct paths are not being treated as interchangeable.

Correlated production evidence

All times below are October 3, 2026 UTC. Private request IDs are replaced with consistent aliases; project paths and chat contents are omitted.

Time Event
18:03:23 / 18:03:51 Backend message_processor records receiving plugin/installed requests P1/P2/P3.
18:03:53.622 / .797 / .798 Renderer logs mcp_request_timeout for those same three IDs, background priority, timeoutMs=30000.
18:04:21.699 / 18:05:40.120 Queue-rejection snapshots show in-flight counts 3, then 4.
19:57:06 / 19:57:36 Backend records receipt of critical config/read IDs C1/C2.
19:57:36.488 / 19:58:06.644 Those two reads time out in the renderer; subsequent snapshots show in-flight counts 5, then 6.
19:58:06.773 Composer logs submission failure with Timeout.
19:59:57.834 Queue rejection reports inFlightRequestCount=8; critical and interactive requests are queued.

Searching codex_app_server* log targets from October 3 18:03 UTC through October 4 06:02 UTC found receipt entries but no matching outgoing entry for those five IDs. The inspected main logs likewise had no matching response for those IDs. This establishes server receipt; absence of a matching log is not proof that every underlying operation never completed. The complete historical eight-slot inventory is unavailable.

During the affected period, other calls such as thread/queue/list and thread/realtime/listVoices still returned in approximately 2–3 ms. The evidence does not show the whole app-server process was completely dead.

Build-specific code pointers

These are zero-based decoded JavaScript character offsets, not original TypeScript line numbers. They refer to the installed app.asar; the desktop source repository was not available.

Bundle Offset / symbol Role
.vite/build/bootstrap-CZlEGA2m.js 1325055, cj=8 Total in-flight cap
Same 1329586, Tj.pumpQueue Dispatch removes queue timer
Same 1300150, cA.abandonDestination Sent-read retention and method-specific exceptions
Same 1328184, dropUnsentRequest Sent requests are not dropped
Same 1330456 / 1329185 Admission cap / queued-only expiry
Same 1439086, failPendingClientRequests Teardown clears state
webview/assets/app-shared-2d992d47c83d.js 3187736–3189131 Renderer timeout/clear/capacity-release methods
Same 5231719 Background installed-inventory query; 30s timeout
.vite/build/main-C_jM0dPl.js 2049573 Abandon IPC forwarding

ASAR SHA-256: af98213984ec4556778ef9276193d51460153fb9b30fded882d503637b84abba.

Suggested fix directions — proposals, not a validated production patch

  1. Define bounded lifecycle handling for already-sent reads after caller timeout: cancellation where supported, or bounded detached-response tracking plus a connection-health/recovery policy. Consider applying a reviewed policy to plugin/installed rather than leaving it outside plugin/list's recovery behavior.
  2. Preserve safe late-response delivery, coalesced waiters and unknown mutation outcomes. Do not simply call complete() for every timeout or blindly replay mutations: physical backend work may still be running, and unlimited replacement requests could accumulate.
  3. Coalesce/rate-limit repeated inventory/config reads where semantics permit; keep discovery failures from consuming all capacity needed for interactive recovery. Raising the cap alone only delays saturation.
  4. Surface stalled-host state and an explicit recovery control even when transport status is still connected. Windows stdio reconnect closes the backend child even with killCodexProcess:false; disclose and handle the impact on other active work.
  5. Instrument each occupied request with method, age, owner, priority, sent/caller-timeout state, backend phase and settlement timestamps. This is needed to identify the initial missing-response cause.

Suggested regression checks: the mixed-read test above; bounded physical in-flight work after timeout; late replies; coalesced caller abandonment; plugin/list/plugin/installed parity where appropriate; mutation reconciliation without duplicate execution; and recovery while other turns/process sessions exist.

The runtime's initial non-response remains unresolved. The corresponding 0.160.0 plugin handler awaits configuration/context, local marketplace work and potentially remote installed-plugin fetching. Available logs do not select one of those stages as the cause. No installed app patch, cache reset, plugin disablement, or live fault injection was performed during this investigation.

Related reports

Only selected diagnostic fields and a synthetic extractor/harness are included. No raw logs, credentials, private paths, project code, conversation contents or live session/request identifiers are attached.

Standalone offline reproduction (Python 3.11+ and Node.js; exact reported build)

Save as codex_queue_repro.py and run python codex_queue_repro.py "<path-to-app.asar>". The script checks the exact ASAR digest, reads implementation snippets from your own installation, and executes them with a fake transport in a separate Node process. It does not distribute the extracted bundle, access your chats, or modify the running app. PASS means the retention failure and control behavior were reproduced, not that the app is fixed.

"""Build-specific offline reproduction for OpenAI.Codex 26.930.3930.0.
Python 3.11+ and Node.js required. Usage: python codex_queue_repro.py <path-to-app.asar>
Reads installed JavaScript and executes only scheduler/client-queue/timeout methods
with a fake transport. No network, credentials, tasks, config writes, or live app calls.
Does not reproduce the original backend hang or apply a repair.
"""
from pathlib import Path
import json
import struct
import subprocess

import argparse
import hashlib
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("asar", type=Path)
args = parser.parse_args()
package = args.asar
with package.open("rb") as digest_stream:
    digest = hashlib.file_digest(digest_stream, "sha256").hexdigest()
expected = "af98213984ec4556778ef9276193d51460153fb9b30fded882d503637b84abba"
if digest != expected:
    raise SystemExit("Different app.asar build; this extractor is build-specific. No test executed.")
with package.open("rb") as handle:
    header = struct.unpack("<4I", handle.read(16))
    tree = json.loads(handle.read(header[3]))
    meta = tree["files"][".vite"]["files"]["build"]["files"]["bootstrap-CZlEGA2m.js"]
    handle.seek(8 + header[1] + int(meta["offset"]))
    source = handle.read(meta["size"]).decode()

scheduler = source[source.index("var cj=8,"):source.index("var Oj=6e4,")]
client_queue = source[source.index("function aA(e)"):source.index("var mA=class")]
unknown_method_predicate = source[source.index("function Hc(e)"):source.index("var Uc=class")]
harness = """
'use strict';
const assert = require('node:assert/strict');
const iA = class {
  captureTrace(){ return undefined; }
  dispatch(_request,_stage,callback){ try { callback(); return null; } catch(error){ return error; } }
  sendErrorResponse(_request,_message,_code,_stage,_op,callback){ callback(undefined); }
  markCoalescedRequestDispatched(request,leader){ request.startedAtMs=leader.startedAtMs; }
  markAbandoned(){}
};
const r={os:value=>value};
const o={M:class extends Error{}};
const Wc=class extends Error{constructor(delivery,error){ super(String(error)); this.delivery=delivery; }};
""" + unknown_method_predicate + scheduler + client_queue + """
const tick=()=>new Promise(resolve=>setImmediate(resolve));
const sender={id:1};
function fixture(){
  const scheduler=new Tj;
  const failures=[],delivery=[],sent=[];
  let client;
  const options={
    requestScheduler:scheduler,transportKind:'fake',ensureReady:async()=>{},
    getPendingRequestCount:()=>client.size,getReconnectAttemptAtEnqueue:()=>0,
    logger:{debug(){},warning(){}},handleRequestFailure(){},
    sendErrorResponse:(_sender,id,error,code)=>failures.push({id,error,code}),
    sendDeliveryUpdate:(_sender,event)=>delivery.push(event),
    sendRequest:request=>sent.push(request.id),
  };
  client=new cA(options);
  return {scheduler,client,failures,delivery,sent};
}
"""
with package.open("rb") as handle:
    header = struct.unpack("<4I", handle.read(16))
    tree = json.loads(handle.read(header[3]))
    node = tree
    for part in "webview/assets/app-shared-2d992d47c83d.js".split("/"):
        node = node["files"][part]
    handle.seek(8 + header[1] + int(node["offset"]))
    shared = handle.read(node["size"]).decode()

start = shared.index("onTimeout(e){let t=this.requestPromises")
end = shared.index("resumeQueueAfter(e){", start)
actual_timeout_methods = shared[start:end]
prefix = harness
source = prefix + """
const timeoutLogs=[];
const nf={warning:(message,fields)=>timeoutLogs.push({message,fields})};
const f6=()=>{};
const ksn=()=>({});
const window={clearTimeout};
class RendererProbe {
  constructor(backend){
    this.hostId='local'; this.useHostRequestScheduler=true;
    this.requestPromises=new Map; this.inFlightRequests=new Set;
    this.inFlightRequestCount=0; this.noncriticalRequestCount=0;
    this.events=[]; this.rejections=[]; this.abandoned=[];
    this.dispatchMessage=(type,message)=>{
      assert.equal(type,'mcp-request-abandon');
      this.abandoned.push(message.requestId);
      backend.client.abandon(sender,message.requestId);
    };
  }
  track(id,method,priority){
    const request={method,priority,source:method==='plugin/installed'?'plugins':'metadata',
      queuedAtMs:Date.now(),startedAtMs:Date.now(),timeoutMs:30000,
      capacityReleased:false,reject:error=>this.rejections.push({id,message:error.message})};
    this.requestPromises.set(id,request); this.inFlightRequests.add(request);
    this.inFlightRequestCount++;
    if(priority!=='critical') this.noncriticalRequestCount++;
  }
  // These callbacks are instrumentation only; no renderer queue is needed
  // because the real useHostRequestScheduler path drains to Electron.
  resumeQueueAfter(){}
  emitRequestLifecycleEvent(event){ this.events.push(event); }
""" + actual_timeout_methods + """
}
(async()=>{
  const mixed=fixture(),renderer=new RendererProbe(mixed);
  for(let id=1;id<=3;id++){
    mixed.client.enqueue(sender,{id,method:'plugin/installed',params:{cwds:[`fixture-${id}`]}},false,{priority:'background',timeoutMs:30000});
    renderer.track(id,'plugin/installed','background');
  }
  await tick();
  assert.equal(mixed.sent.length,3);
  for(let id=1;id<=3;id++) renderer.onTimeout(id);
  assert.equal(renderer.inFlightRequestCount,0);
  assert.equal(mixed.scheduler.getQueueState().inFlightRequestCount,3);
  for(let id=4;id<=8;id++){
    mixed.client.enqueue(sender,{id,method:'config/read',params:{cwd:`fixture-${id}`,includeLayers:false}},false,{priority:'critical',timeoutMs:30000,coalesce:false});
    renderer.track(id,'config/read','critical');
  }
  await tick();
  for(let id=4;id<=8;id++) renderer.onTimeout(id);
  assert.equal(renderer.inFlightRequestCount,0);
  assert.equal(renderer.requestPromises.size,0);
  assert.equal(renderer.abandoned.length,8);
  assert.equal(mixed.scheduler.getQueueState().inFlightRequestCount,8);
  for(let id=9;id<=10;id++){
    mixed.client.enqueue(sender,{id,method:'config/read',params:{cwd:'retry'}},false,{priority:'critical',timeoutMs:5,coalesce:false});
    await new Promise(resolve=>setTimeout(resolve,15));
  }
  assert.equal(mixed.sent.length,8);
  assert.equal(mixed.failures.length,2);
  assert.ok(mixed.failures.every(error=>error.code===-32001));
  assert.equal(mixed.scheduler.getQueueState().inFlightRequestCount,8);
  mixed.scheduler.clear(); mixed.client.clear();

  const list=fixture();
  for(let id=1;id<=3;id++) list.client.enqueue(sender,{id:`plugin/list:${id}`,method:'plugin/list',params:{cwds:[`fixture-${id}`]}},false,{priority:'background',timeoutMs:30000,coalesce:false});
  await tick();
  assert.equal(list.scheduler.getQueueState().inFlightRequestCount,3);
  for(let id=1;id<=3;id++) list.client.abandon(sender,`plugin/list:${id}`);
  assert.equal(list.scheduler.getQueueState().inFlightRequestCount,0);
  assert.equal(list.client.size,0);
  list.scheduler.clear(); list.client.clear();
  console.log(JSON.stringify({result:'PASS',experiment:'cross-layer historical method mixture',
    actualMethods:{frontendTimeoutOffset:""" + str(start) + """,frontendTimeoutEndOffset:""" + str(end) + """},
    observations:[
      'Three background plugin/installed timeouts free renderer capacity but retain three Electron slots',
      'Five critical config/read timeouts free renderer capacity but fill remaining Electron slots',
      'Two retries both expire -32001 and neither reaches fake transport',
      'Equivalent plugin/list abandonment releases all three slots via special detach path'
    ],limitations:[
      'Fake transport intentionally never responds; historical initiating cause is not recreated',
      'Frontend onTimeout invoked directly rather than waiting thirty seconds',
      'Retry queue deadline scaled to five milliseconds',
      'Renderer tracing and capacity-resume callbacks stubbed; installed onTimeout/clear/release methods used verbatim'
    ]},null,2));
})().catch(error=>{ console.error(error); process.exitCode=1; });
"""
result = subprocess.run(["node", "-"], input=source, capture_output=True, text=True, timeout=15)
print(result.stdout, end="")
if result.stderr:
    print(result.stderr, end="")
raise SystemExit(result.returncode)

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
    on Oct 4, 2026
  2. jibe-dev-ship-it commented on Oct 4, 2026

    @jibe-dev-ship-it

    Thank you for analyzing how host request slots can remain occupied after caller timeouts and block Send/Retry. Inter-task communication also stalls on my Windows installation (26.930.2377.0, build 12776), so this analysis is a useful lead for comparison and investigation.

    My symptoms include:

    • White-screen/Home reloads sometimes erase unsent text or dictation.
    • Clicking, typing, scrolling, and switching tasks delay or freeze.
    • Some existing conversations fail to load in Chrome and the Windows app.
    • Inter-task send/read/list/status calls fail, or their functions become unavailable.

    The PC app remains unusable for my work, so I am relying on my iPad. My case has been escalated to the technical team, and Support has confirmed from the submitted recordings and logs that the reported failures are actually occurring. Nevertheless, more than 50 hours have passed since their last reply, with no further response or concrete solution. There is still no official incident notice for this Windows desktop issue.

    I am sharing my report as comparison material. By pooling evidence about where communication stops, we can jointly call for a prompt resolution and a clear response to the disruption preventing us from working.

  3. grtninja commented on Oct 7, 2026

    @grtninja

    Additional Windows observation on October 7, 2026, on desktop package 26.1002.6548.0 with bundled app-server 0.162.0-alpha.2 (separate PATH CLI 0.160.1).

    Around 03:46 UTC I encountered an app-server queue-full error and could not resume a chat. I manually restarted at 03:50:37 UTC. Retained logs then show two thread/resume response_routed entries with errorCode=null and no matching failure events: 03:51:03.018 UTC (578 ms) and 03:51:57.161 UTC (1,094 ms), both queueWaitMs=0. Result payloads were not logged, so complete UI reopening is not established.

    This corroborates the user-visible queue-blocked continuation symptom on a newer package, not this issue's precise eight-slot retention mechanism. I do not have the pre-restart occupied-request inventory or current queue depth.

    Separately, post-restart background hydration generated 742 distinct thread/read requests across 157 conversations ending in -32003 access-denied responses, with 0–1 ms queue waits. That distinct observation is reported in #51572; no causal link to the earlier queue-full event is established. Private identifiers, paths, conversation content and raw logs are omitted. Please identify supported diagnostics/recovery that preserve existing chat history and active work.

  4. 0xdevalias commented on Oct 17, 2026

    @0xdevalias

    Current macOS build 26.1007.71326 (20398) independently exhibits the dispatched ordinary-read abandonment gap in the shipped abandonDestination method: plugin/installed, account/read, and getAuthStatus remain pending after a window abandons a dispatched request, whereas plugin/list detaches and thread/resume completes. Full provenance, real demand/deadline data, actual scheduler probes and limitations: #53197 (comment) . This supports the cross-platform retention mechanism; it does not establish that all eight slots are currently retained on the examined Mac.

  5. darmcys11 commented on Oct 17, 2026

    @darmcys11

    Additional Windows-to-Windows Remote Control evidence from 2026-10-17, on a newer matching installation on both computers:

    • Windows 11, OS 10.0.26200 (both hosts).
    • Codex MSIX package 26.1013.4894.0 (both hosts).
    • Bundled codex-cli 0.163.0-alpha.10.2 (both hosts).
    • The initiating desktop's built-in update check reported up_to_date. Its UI version was 26.1013.40934 / build 20770; package and UI numbering are reported separately here.

    Observed failure and recovery (UTC; request identifiers and private host/session information omitted):

    1. At 11:45:49.364, callers of thread/read and thread/turns/list timed out after approximately 15 seconds.
    2. The same two dispatched reads remained pending. Subsequent reads expired after approximately 60 seconds with inFlightRequestCount=2. This concerns the background read lane; I am NOT claiming that all eight host slots were occupied in this incident.
    3. At 11:56:32.220, the remote stream closed with code 4000 / "stream became unknown". At 11:56:32.231, those original pending reads finally received "Codex app-server is not available" errors. Thus caller timeout had not bounded their pending lifetime; they survived for roughly eleven minutes until transport teardown.
    4. Later, at 14:23:18.801, another "stream became unknown" close occurred with two pending requests. A new transport started at 14:23:22.912 and connected at 14:23:24.766, without an operator restart.

    The remote computer and app remained running. Fresh remote-side inventory and independently saved task completion were available even when the initiating desktop's native thread-status query could not determine whether the thread existed. Successful native reads were also observed between failures. An unavailable read therefore did not mean the remote computer had powered off or the conversation was missing.

    Configuration caveat: a custom loopback shared App Server was introduced on the remote host at 12:16:35 UTC. The initial 11:45 incident preceded that change; later observations involve that configuration. This chronology does not rule out configuration effects on later incidents, nor establish that the relay/network was continuously healthy.

    Bounded control test: I launched the same installed 0.163.0-alpha.10.2 binary in a disposable empty CODEX_HOME over stdio, with no copied authentication or real conversations and no model calls. Initialize, eight pairs of thread/read + thread/turns/list using a synthetic missing UUID, and thread/list all returned promptly (the missing-thread calls returned structured -32600 errors), followed by clean process exit. This only demonstrates basic healthy direct-transport handling; it does NOT reproduce dropped relay responses, desktop request abandonment, or reads of production histories.

    I also inspected the public App Server source at the installed tag rust-v0.163.0-alpha.10.2, commit 4ebc485. That inspection and the control test do not establish a public Rust App Server defect or a justified server-side patch. The desktop pending-request recovery gap appears consistent with this issue; the cause of the first missing response remains unresolved. The stream-reset symptom may also relate to #32241, without asserting a shared root cause.

    Could maintainers confirm whether a caller-abandoned ordinary read should release its scheduler capacity (or be detached with generation-safe late-response handling), and whether a shipped fix/version exists? Expected behavior is bounded recovery for later reads without requiring an app restart, while preserving already-running work.

    No credentials, conversation bodies, private endpoint/session identifiers, or proprietary application source are included in this report.

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