Skip to content

ChatGPT/Codex Desktop main window renders empty (or "Work" shell with endless spinner) on first load after every update since 26.901.2854.0; only a DevTools Page.reload fixes it #43960

Open

Description

@rmacx

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

26.901.6511.0 (MSIX package OpenAI.Codex_26.901.6511.0_x64__2p2nqsd0c76g0). Also reproduced on 26.901.2854.0 (Sept 3) and 26.901.5280.0 (Sept 5). Embedded Chromium 152.0.7977.83, bundled codex-cli 0.153.4.

What subscription do you have?

ChatGPT Pro

What platform is your computer?

Microsoft Windows 11 Pro 25H2, build 10.0.26200, x64. Dell Precision 7920 (Xeon Silver 4110, NVIDIA Quadro P5000, driver 32.0.15.8278). Single 2560x1080 display, 100% scaling. No proxy, no VPN on the default route (WireGuard and Tailscale adapters present but not default).

What issue are you seeing?

Since the update to 26.901.2854.0 on Sept 3, 2026, the main window never renders correctly on its first load. Every launch ends in one of two states:

  1. Fully empty window: only the gradient background and the min/max/close buttons. The DOM of app://-/index.html has ~23 elements: #root contains only the pre-mounted (inert/invisible) pricing overlay, nothing else. body.innerText is empty.
  2. "Work" shell without composer: the sidebar renders (header shows "Work", projects list), the center shows the OpenAI logo spinner forever, projects show "Carregando chats"/"Loading chats" forever, and there is no message composer (document.querySelectorAll('input, textarea, [contenteditable]') = 0).

Everything else is healthy in the app's own logs (LocalCache\Local\Codex\Logs\...): all processes Responding=True, no crash, no render-process-gone, app_server_connection reaches initialize_handshake_result outcome=success in ~1 s, getAuthStatus / account/read / model/list / config/read all answer with errorCode=null in < 250 ms, [chatgpt-account-lookup] completed ... authenticatedAccountPresent=true result=succeeded, window main frame finished load and ready-to-show fire normally, and [startup][renderer] app routes mounted after ~6700ms is logged for the primary window.

What the renderer console says on load (captured through CDP Runtime.consoleAPICalled):

Matched leaf route at location "/" does not have an element or Component.
This means it will render an <Outlet /> with a null value by default resulting in an "empty" page.

The only thing that fixes it is reloading the same webContents: launching the app with --remote-debugging-port=N and sending Page.reload {ignoreCache:true} to the app://-/index.html target. After the reload the DOM goes from ~23 elements / 0 text / 0 inputs to ~1750 elements / ~1500 chars / 2 inputs, the header switches from "Work" to "ChatGPT", projects and recent conversations load, and the composer appears. The reload also triggers main-process work that never happened in the broken state: bundled_plugins_reconcile_started reason=startup, browser_use_iab_backend_startup_started, chatgpt_conversation_updates_subscription_mounted, and app/installed + app/read requests to the app-server. In the broken state main keeps logging bundled_plugins_reconcile_skipped_features_unavailable reason=focus on every focus.

On Sept 3 a single reload was enough and subsequent normal launches worked. Since Sept 5, every normal launch (7 of 7 on Sept 5, again on Sept 8) is broken again; only an instance kept running with the debugging port open is usable.

Two other warnings appear at every start, in working and broken instances alike, so they are probably unrelated: Failed to start the Artifact Session host errorMessage="Artifact Session host Unix-socket transport is not available on Windows." and two fs/readFile requests failing with os error 3 (path not found) right after startup.

What steps can reproduce the bug?

Feedback ID: no-active-thread-01a08355-ffb9-7ef0-b1ca-470e3be31017

What is the expected behavior?

The main window renders the ChatGPT UI (sidebar, conversations, projects, composer) on the first load, without needing a manual reload through the debugging protocol.

Additional information

Activity

  1. added
    appIssues related to the Codex desktop app
    on Sep 9, 2026
  2. added
    bugSomething isn't working
    windows-osIssues related to Codex on Windows systems
    on Sep 9, 2026
  3. kylerjkirk commented on Sep 26, 2026

    @kylerjkirk

    Same bug on 26.924.1866.0 (MSIX OpenAI.Codex_26.924.1866.0_x64__2p2nqsd0c76g0, build 11431, commit 97cf4a3c), Windows 10 Pro 22H2 (19045), NVIDIA RTX 2080.

    It started with the update from 26.917 (build 10954). My last launch on 26.917 loaded normally. Every launch on 26.924 failed.

    Same fingerprints as the original report:

    • Renderer console: Matched leaf route at location "/" does not have an element or Component
    • Every failed launch logs name=app_start outcome=failure reason=timeout at about 122 s. Marks reach settings_ready (about 4 s) and never reach shell_visible or home_visible.
    • The app-server is healthy but never receives thread/list, thread/read, model/list or skills/list. It only sees initialize, experimentalFeature/enablement/set and remoteControl/enable.
    • The main log shows bundled_plugins_reconcile_skipped_features_unavailable on every failed launch.
    • Setting aside ~/.codex/.codex-global-state.json did not help.

    Your Page.reload workaround fixes it here too. I launched with --remote-debugging-port (127.0.0.1) and sent Page.reload {ignoreCache:true} to app://-/index.html. The DOM went from 55 elements, no text and no inputs to 3,287 elements with the composer. That launch logged app_start outcome=success at 6.2 s (home_visible 5.4 s, sidebar_ready 6.2 s), followed by thread/list and thread/read.

    Separate from #48216: that one reaches thread/list and thread/read and then fails on Conversation state not found. In my failed launches the renderer never sends thread/list at all.

  4. A10nEsK commented on Sep 27, 2026

    @A10nEsK

    @rmacx @kylerjkirk — fuller independent Windows cold-start reproduction, with a controlled test of the startup gate. This was tested on a different installation running Windows Store/MSIX Stable OpenAI.Codex 26.924.2738.0 (bundled app-server 0.158.0-alpha.2.1). It is evidence about this installation; I cannot establish that every build in the original report fails through the same code path.

    Failure signature

    On an ordinary cold launch, app://-/index.html finished loading but the primary window remained on the spinner. The React startup state was fulfilled, the route was initialized and idle, and account feature access was allowed.

    The main-process log already had the app-server version, initialization, and connection before the primary frame finished loading: 08:27:06.860 (version), .861 (initialized), .864 (connected), .867 (primary frame finished loading). In the renderer, appServerVersion$ remained unset and the host state initially remained disconnected.

    Direct inspection of the renderer state showed gateway OAuth readiness returning loading because the app-server-version dependency was null. The query cache had no gateway-oauth/read entry at all, so this was not a gateway request that had been sent and left pending.

    Controlled checks

    • Changing only the renderer connection state to connected did not recover the UI.
    • Setting only appServerVersion$ to the exact version already reported by the app-server created the internal gateway-oauth/read query, which reached success in about 250 ms. This isolates the missing version as a prerequisite for the request; that state-injection probe by itself did not independently verify that the full UI had mounted.
    • On a separate clean cold launch, replaying the app's own {type: "ready", initializationOnly: true} message caused the initialization snapshot to be delivered again. The interface began mounting within about one second, without a page reload or a fabricated version value; the gateway query also reached success.
    • A renderer Page.reload in the same process also restored the interface. Closing and cold-starting Stable reproduced the spinner.

    Likely mechanism and scope

    Inspection of the packaged flow is consistent with an initialization-snapshot race: the renderer stores the version only when it handles codex-app-server-initialized; the main process sends initialization state in response to renderer ready; and the desktop-message buffer does not retain this event before the general renderer handler subscribes. If the snapshot arrives in that gap, gateway readiness can remain loading indefinitely. Replaying ready is a direct recovery for this installation.

    This is strong causal evidence for the immediate blocker on this machine. The event-order explanation is supported by the packaged code and recovery test, but has not been confirmed as the upstream root cause by a maintainer.

    This appears closely related to the first-load/reload symptom in this issue. It is a different failure stage from #48216's successful thread/list / thread/read calls followed by Conversation state not found: in this reproduction, the primary renderer is blocked before it creates the gateway query needed to proceed.

    Could the team check whether the initialization snapshot can arrive before the renderer handler is subscribed, and ensure that startup state is replayed or buffered so the primary window cannot remain on an indefinite spinner? No raw logs, screenshots, account identifiers, or personal filesystem paths are attached.

  5. theodore-td commented on Sep 27, 2026

    @theodore-td

    Additional reproduction on 26.924.2738.0: initialization arrives before renderer listeners

    Adding measured listener timing from this installation, consistent with the initialization-snapshot failure described above.

    Environment

    • Windows x64, 25H2, build 10.0.26200.9457.
    • Store/MSIX package: OpenAI.Codex 26.924.2738.0.
    • Internal desktop version: 26.924.22138, build 11645, prod.
    • App-server: 0.158.0-alpha.2.1.

    Symptoms and isolation
    After closing and reopening, the entire primary window stays blank with a spinner, not just the conversation pane. This also reproduced in isolated cold launches using a separate Chromium profile and a copy of the current minimal Codex home, without restoring the historical backup. The backend initialization handshake and account lookup succeeded.

    Five isolated cold-launch tests recovered visible UI after reloading the same renderer. Two further tests recovered visible content by requesting only the app's existing {type:"ready", initializationOnly:true} snapshot, without page reload, backend restart, fabricated version values, credential changes, or deleting history.

    Measured event order in one snapshot-only test
    An early diagnostic observer recorded selected window messages and message-listener registration; times below are milliseconds relative to page startup:

    Time Observation
    130.5 ms Local connection snapshot: connecting
    189.5 ms Window receives codex-app-server-initialized, version 0.158.0-alpha.2.1; tracked application message listeners: 0
    309.6 ms Message broker registers windowMessageListener
    2160.8 ms Application-state message listener registers
    Approximately 22 s Still zero visible body text with a spinner; request initialization-only snapshot
    22143.7 ms Initialization event arrives again, now isSnapshot=true, with receivers present
    After replay Visible body text changes from 0 to 277 characters

    The broad "any spinning element" check remained true in that instrumented run, so this establishes escape from the empty-window state, not that every background task finished. In the other snapshot-only run the spinner check became false. The isolated profiles can still require Windows sandbox setup; full chat functionality and restored-history behavior were not acceptance-tested.

    Likely mechanism / requested fix
    Local renderer inspection found the app-server version unset and gateway OAuth readiness stuck in loading. Read-only inspection of the installed message path is consistent with an early initialization event being lost before subscribers exist. The checked message buffer did not retain codex-app-server-initialized; requesting the existing snapshot after listener registration unblocked startup.

    Please investigate reliable replay/buffering of initialization state, an explicit snapshot request after receivers are installed, and bounded recovery rather than an indefinite spinner when version state is missing.

    This is single-machine instrumented evidence, not a claim that all blank-window reports share the same cause; instrumentation can affect timing. No signed package files were patched. No raw logs, credentials, conversation contents, account identifiers, or personal filesystem paths are attached.

  6. kyleisbased commented on Sep 29, 2026

    @kyleisbased

    Independent confirmation of this failure signature, plus a launcher-integrated workaround that has been reliable across cold starts on a Windows 11 Store/MSIX installation.

    Observed failure signature

    On a hung cold launch, attached over CDP to the main window (app://-/index.html):

    document.getElementById('root').innerHTML.length : 1236
    document.getElementById('root').innerText.length  : 0
    document.querySelectorAll('*').length             : 55
    

    That matches the measurements in the report above exactly, including innerHTML.length = 1236. The window is OS-responsive, the app-server completes its handshake and answers config/read, account/read, experimentalFeature/list, plugin/installed and skills/list in well under 50 ms each, and auth is valid — but the renderer never sends the follow-up work (no thread/list) and the UI stays on the spinner.

    Consistent with the analysis already posted in this thread, the renderer appears to lose the initialization snapshot because it arrives before the renderer's message listeners are registered, and is not replayed or buffered.

    Two things I can confirm as not causal on my machine:

    • The React Router warning (Matched leaf route at location "/" does not have an element or Component) fires on working and hung launches alike. It is a red herring, as noted above.
    • config.toml content does not control it. I A/B tested a comment-only config, a regenerated config, a deleted config, and an unchanged frozen config across repeated cold launches. A rendered run and a hung run ended up with byte-identical config files (same SHA-256). Removing config.toml occasionally yields one working launch because it forces a fresh handshake — the same reason an external reload works — not because of its contents.

    A practical detail that cost me several failed attempts

    The UI can take a long time to actually paint after the reload is issued. My first attempts polled for ~20 s and concluded failure, then gave up. Any verification loop needs to allow at least 25–30 s after Page.reload before deciding it did not work. Intermittency is also real: I measured roughly 3 of 4 cold launches hanging, consistent with the report above.

    Workaround

    The approach is the one already described (launch with --remote-debugging-port, then drive CDP). What I added, which is what made it dependable as a daily launcher rather than a manual recovery step:

    1. Wait for the app to finish starting (~12 s) before the first repair attempt. Issuing the reload immediately after the debug port opens frequently lands before the shell exists and does nothing.
    2. Retry the repair, re-verifying between attempts, instead of running it once.
    3. Verify against real DOM content (text length, #root child count, spinner count, error-page detection) rather than a loose "is there any text" check. I had an early version that reported success against the browser's own error page because the error text exceeded the threshold, and a separate version that hung indefinitely because the CDP calls had no timeouts.
    4. Fall back cleanly. The launcher logs its outcome to a file rather than showing a modal dialog — a modal on the failure path blocks the desktop until someone clicks it, which is worse than the original bug.

    PowerShell launcher. It reuses an existing session if one is already running, otherwise starts the app with the debug port and repairs it:

    $ErrorActionPreference = 'Stop'
    
    $port   = 9333
    $repair = Join-Path $PSScriptRoot 'repair.mjs'
    $probe  = Join-Path $PSScriptRoot 'probe.mjs'
    
    $node = (Get-Command node -ErrorAction SilentlyContinue).Source
    if (-not $node) { $node = 'C:\Program Files\nodejs\node.exe' }
    
    $package = Get-AppxPackage OpenAI.Codex
    if (-not $package) { throw 'Codex package not installed.' }
    $aumid = "$($package.PackageFamilyName)!App"
    
    Add-Type -TypeDefinition @"
    using System;
    using System.Runtime.InteropServices;
    public static class CodexActivate {
        [ComImport, Guid("45BA127D-10A8-46EA-8AB7-56EA9078943C")]
        private class ApplicationActivationManager { }
        [ComImport, Guid("2e941141-7f97-4756-ba1d-9decde894a3d"),
         InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        private interface IApplicationActivationManager {
            int ActivateApplication([MarshalAs(UnmanagedType.LPWStr)] string appUserModelId,
                [MarshalAs(UnmanagedType.LPWStr)] string arguments, uint options, out uint processId);
            int ActivateForFile(string appUserModelId, IntPtr itemArray, string verb, out uint processId);
            int ActivateForProtocol(string appUserModelId, IntPtr itemArray, out uint processId);
        }
        public static uint Activate(string appUserModelId, string arguments) {
            var manager = (IApplicationActivationManager)new ApplicationActivationManager();
            uint pid;
            int hr = manager.ActivateApplication(appUserModelId, arguments, 0, out pid);
            if (hr < 0) { Marshal.ThrowExceptionForHR(hr); }
            return pid;
        }
    }
    "@
    
    function Test-DebugPort {
        try { $null = Invoke-RestMethod "http://127.0.0.1:$port/json/version" -TimeoutSec 2; return $true }
        catch { return $false }
    }
    
    # Capture the exit code immediately, with no pipeline in between.
    function Test-UiRendered {
        $out = & $node $probe $port 2>&1
        $code = $LASTEXITCODE
        ($out | Out-String).Trim() -split "`n" | ForEach-Object { Write-Host "    $_" }
        return ($code -eq 0)
    }
    
    $logFile = Join-Path $env:LOCALAPPDATA 'CodexLauncherLogs\launch.log'
    New-Item -ItemType Directory -Force -Path (Split-Path $logFile) | Out-Null
    
    if (Test-DebugPort) {
        Write-Host 'Codex already running - will repair it.'
    } else {
        Write-Host 'Starting Codex...'
        Get-Process ChatGPT -ErrorAction SilentlyContinue |
            Where-Object { $_.Path -like "$($package.InstallLocation)*" } |
            Stop-Process -Force -ErrorAction SilentlyContinue
        Start-Sleep -Milliseconds 800
        [void][CodexActivate]::Activate($aumid, "--remote-debugging-port=$port")
    
        $deadline = (Get-Date).AddSeconds(90)
        while (-not (Test-DebugPort)) {
            if ((Get-Date) -gt $deadline) { throw "Debug endpoint never came up." }
            Start-Sleep -Milliseconds 500
        }
    }
    
    # Let the shell mount before steering it - this is the step that mattered.
    Write-Host 'Letting the app finish starting...'
    Start-Sleep -Seconds 12
    
    $attempts = 4
    for ($i = 1; $i -le $attempts; $i++) {
        Write-Host "Repair attempt $i of $attempts..."
        if (Test-UiRendered) {
            Write-Host 'Codex is ready.' -ForegroundColor Green
            Add-Content $logFile "$(Get-Date -f s) rendered (attempt $i)"
            exit 0
        }
        & $node $repair $port
        Start-Sleep -Seconds 4
        if (Test-UiRendered) {
            Write-Host 'Codex is ready.' -ForegroundColor Green
            Add-Content $logFile "$(Get-Date -f s) rendered after repair (attempt $i)"
            exit 0
        }
    }
    
    Add-Content $logFile "$(Get-Date -f s) NOT rendered after $attempts attempts"
    Write-Host 'Window still not rendering. Run the shortcut again.' -ForegroundColor Yellow
    exit 1

    repair.mjs — targets the main window explicitly, re-requests the initialization snapshot first (works for some reporters, not on my build), then falls back to a reload, and allows 40 s for the UI to appear:

    const PORT = Number(process.argv[2] || 9333);
    const WAIT_MS = Number(process.argv[3] || 40000);
    const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
    const isMain = (u) => !u.includes('initialRoute') &&
      (u === 'app://-/app' || u === 'app://-/index.html' || u === 'app://-/');
    
    async function listPages() {
      const r = await fetch(`http://127.0.0.1:${PORT}/json/list`);
      return (await r.json()).filter((t) => t.type === 'page');
    }
    
    function connect(url) {
      return new Promise((resolve, reject) => {
        const ws = new WebSocket(url);
        const pending = new Map();
        let id = 1;
        const timer = setTimeout(() => reject(new Error('connect timeout')), 10000);
        ws.addEventListener('open', () => {
          clearTimeout(timer);
          ws.addEventListener('message', (ev) => {
            let m; try { m = JSON.parse(ev.data); } catch { return; }
            const p = pending.get(m.id);
            if (!p) return;
            pending.delete(m.id); clearTimeout(p.timer);
            m.error ? p.reject(new Error(m.error.message)) : p.resolve(m.result);
          });
          resolve({
            call: (method, params = {}, ms = 15000) => new Promise((res, rej) => {
              const i = id++;
              const t = setTimeout(() => { pending.delete(i); rej(new Error(method + ' timeout')); }, ms);
              pending.set(i, { resolve: res, reject: rej, timer: t });
              try { ws.send(JSON.stringify({ id: i, method, params })); } catch (e) { clearTimeout(t); rej(e); }
            }),
            close: () => { try { ws.close(); } catch {} },
          });
        });
        ws.addEventListener('error', () => { clearTimeout(timer); reject(new Error('ws error')); }, { once: true });
      });
    }
    
    async function state(call) {
      try {
        const r = await call('Runtime.evaluate', {
          expression: `(() => {
            const t = document.body ? document.body.innerText.trim() : '';
            const root = document.getElementById('root');
            return [t.length, root ? root.innerHTML.length : -1,
                    document.querySelectorAll('.animate-spin').length,
                    t.includes('reached') ? 'ERR' : 'OK'].join('|');
          })()`,
          returnByValue: true,
        }, 6000);
        const [len, rootLen, spins, flag] = String(r.result?.value ?? '-1|-1|-1|OK').split('|');
        return { len: +len, rootLen: +rootLen, spins: +spins, errorPage: flag === 'ERR' };
      } catch { return { len: -1, rootLen: -1, spins: -1, errorPage: false }; }
    }
    
    const good = (s) => s.len > 60 && !s.errorPage;
    
    let main = null;
    for (let i = 0; i < 20 && !main; i++) {
      try { main = (await listPages()).find((t) => isMain(t.url)); } catch {}
      if (!main) await sleep(500);
    }
    if (!main) { console.log('no main window'); process.exit(3); }
    
    const conn = await connect(main.webSocketDebuggerUrl);
    try { await conn.call('Page.enable', {}, 8000); } catch {}
    try { await conn.call('Runtime.enable', {}, 8000); } catch {}
    
    let s = await state(conn.call);
    if (good(s)) { console.log('already rendered'); conn.close(); process.exit(0); }
    
    // Strategy 1: replay the app's own initialization snapshot (no reload).
    console.log('snapshot replay (best effort)');
    try {
      await conn.call('Runtime.evaluate', {
        expression: `window.postMessage({ type: 'ready', initializationOnly: true }, '*')`,
        returnByValue: true,
      }, 6000);
    } catch {}
    
    let deadline = Date.now() + Math.min(WAIT_MS, 20000);
    while (Date.now() < deadline) {
      await sleep(1000);
      s = await state(conn.call);
      if (good(s)) { console.log(`rendered via snapshot replay (${s.len})`); conn.close(); process.exit(0); }
    }
    
    // Strategy 2: reload the renderer.
    console.log('reloading renderer');
    try { await conn.call('Page.reload', { ignoreCache: true }, 15000); } catch {}
    
    deadline = Date.now() + WAIT_MS;
    while (Date.now() < deadline) {
      await sleep(1500);
      s = await state(conn.call);
      if (good(s)) { console.log(`rendered via reload (${s.len})`); conn.close(); process.exit(0); }
    }
    console.log(`failed (text=${s.len} rootHtml=${s.rootLen} spinners=${s.spins})`);
    conn.close(); process.exit(1);

    probe.mjs — the pass/fail check. Only the main window counts; the app always has background windows (detached-window.html, avatar-overlay via initialRoute) that legitimately never paint, and judging those makes the result meaningless:

    const PORT = Number(process.argv[2] || 9333);
    const isMain = (u) => !u.includes('initialRoute') &&
      (u === 'app://-/app' || u === 'app://-/index.html' || u === 'app://-/');
    
    try {
      const list = await (await fetch(`http://127.0.0.1:${PORT}/json/list`)).json();
      const main = list.filter((t) => t.type === 'page').find((t) => isMain(t.url));
      if (!main) { console.log('MAIN WINDOW NOT FOUND'); process.exit(3); }
    
      const ws = new WebSocket(main.webSocketDebuggerUrl);
      const pending = new Map(); let id = 1;
      await new Promise((res, rej) => {
        ws.addEventListener('open', res, { once: true });
        ws.addEventListener('error', rej, { once: true });
      });
      ws.addEventListener('message', (e) => {
        const m = JSON.parse(e.data); const p = pending.get(m.id);
        if (!p) return; pending.delete(m.id);
        m.error ? p.reject(new Error(m.error.message)) : p.resolve(m.result);
      });
      const call = (method, params = {}) => new Promise((res, rej) => {
        const i = id++; pending.set(i, { resolve: res, reject: rej });
        ws.send(JSON.stringify({ id: i, method, params }));
      });
      await call('Runtime.enable');
      const ev = async (x) => (await call('Runtime.evaluate', { expression: x, returnByValue: true })).result?.value;
    
      const textLen = await ev('document.body ? document.body.innerText.trim().length : -1');
      const rootKids = await ev('document.getElementById("root") ? document.getElementById("root").children.length : -1');
      const preview = String(await ev('document.body ? document.body.innerText.trim().slice(0,110) : ""'));
      ws.close();
    
      const ok = textLen > 60 && rootKids > 0 && !preview.includes('reached');
      console.log(`text=${textLen} rootKids=${rootKids} verdict=${ok ? 'RENDERED' : 'BLANK'}`);
      process.exit(ok ? 0 : 1);
    } catch (e) { console.log('probe error: ' + e.message); process.exit(4); }

    Measured results

    With the version that fired the repair immediately after the debug port opened: 0 of 4 cold starts rendered. With the wait-then-retry version: 7 of 7 cold starts rendered, and after consolidating the scripts, a further 3 of 3.

    Caveats

    • This works around a renderer bug; it does not fix it, and it leaves a local debugging port open on 127.0.0.1 while the app runs, which is not an acceptable permanent state.
    • It is verified only against a Windows 11 Store/MSIX install. The timing constants (12 s head start, 40 s paint allowance, 4 attempts) may need adjusting on slower or faster machines.
    • The underlying fix still needs to come from the app: buffer or replay the initialization state, and add a bounded recovery instead of an indefinite spinner.

    Thanks to everyone who documented the mechanism above — the listener-timing measurements in this thread are what made this reproducible rather than guesswork.

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 appbugSomething 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