Skip to content

[Windows][Desktop] Browser tab RPCs block on unbounded request-header identity lookup #45014

Open

Description

@yuelinyayun-star

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

Codex Desktop 26.903.9818.0

What subscription do you have?

ChatGPT subscription (exact tier not relevant to the reproduction and not verified for this report).

What platform is your computer?

Microsoft Windows NT 10.0.26200.0 x64

Additional tested components:

  • @oai/browser-desktop 0.1.1
  • bundled Node.js v24.20.0
  • Microsoft Edge 152.0.4191.66
  • ChatGPT browser extension 1.26.901.11451

What issue are you seeing?

Codex Desktop discovers the Edge extension-backed browser, but tab-level RPC calls such as openTabs() wait approximately 21 seconds and then fail with:

nodeRepl.fetch request failed

The extension installation, native host, and tab itself are not the failing boundary. During instrumentation:

  • browser/provider discovery succeeds;
  • getInfo reaches the extension;
  • the native host is running;
  • openTabs and related tab RPCs do not reach extension dispatch before the timeout.

The bundled browser service blocks before its send/request path while waiting for the caller-identity promise used by the optional request-header policy. The identity comes from:

https://chatgpt.com/backend-api/aura/identity

The vulnerable minified function in this build waits for that promise without a timeout before reading codex_browser_use_agent_request_header. If identity never settles, unrelated browser RPCs are held until the outer transport surfaces the opaque fetch error.

This is more specific than the same outward symptom reported in #44390, #44697, #44500, #44135, and #43787: this report includes a reproduced blocking dependency, a bounded workaround, and before/after measurements.

What steps can reproduce the bug?

  1. Run Codex Desktop 26.903.9818.0 on Windows.
  2. Enable the official ChatGPT browser extension in Edge.
  3. Verify that Codex discovers Edge as an extension-backed browser.
  4. In a fresh local task, select Edge and call browser.user.openTabs() or an equivalent tab-list operation.
  5. Observe that the call waits roughly 21 seconds and fails with nodeRepl.fetch request failed.
  6. Instrument the bundled browser service and observe that the call is blocked while resolving the agent request-header policy, before the browser RPC is sent to the extension.

A local, reversible workaround was validated by making the policy lookup bounded:

let requestHeaderPolicyPromise;

async function shouldUseAgentRequestHeader() {
  return requestHeaderPolicyPromise ??= (async () => {
    if (callerIdentityPromise == null) return false;

    try {
      return await Promise.race([
        callerIdentityPromise.then(() =>
          readPolicy("codex_browser_use_agent_request_header")
        ),
        new Promise((resolve) => setTimeout(() => resolve(false), 2500)),
      ]);
    } catch {
      return false;
    }
  })();
}

This preserves the real policy when identity resolves promptly, falls back to false after 2.5 seconds or rejection, and caches the bounded result.

Reproduction notes and an idempotent backup/restore PowerShell workaround are available here:

https://github.com/yuelinyayun-star/codex-browser-request-header-timeout-fix

The repository does not redistribute OpenAI's runtime.

What is the expected behavior?

Browser RPC dispatch should not depend indefinitely on identity telemetry or an optional request-header decision.

If the identity request stalls or fails, Codex should either:

  • continue after a bounded fallback without the optional header; or
  • return a specific, actionable policy/identity error.

It should not hold all tab RPCs until they become nodeRepl.fetch request failed.

Additional information

Validated results on the affected machine:

Operation Before workaround After workaround
Browser discovery succeeds about 299 ms
First openTabs() fails after about 21 s about 2534 ms
Subsequent tabs.list() fails or never dispatches about 3 ms

After the workaround:

  • bundled node --check passes;
  • Edge tabs can be enumerated;
  • a real tab can be claimed;
  • title and URL can be read;
  • the prior fetch failure does not recur in this request path.

The original tested browser-service.mjs SHA-256 is:

C96DBF28F0854B00B0CF79E936ADFB3754ECB6B0714F94C50A594D3B68940E3E

A separate intermittent Debugger unattached state can still occur after a CUA kernel reset or navigation. That is not claimed to be fixed by this workaround.

Requested upstream changes:

  • add a bounded timeout and rejection handling around identity-dependent request-header policy;
  • avoid coupling optional header policy to all browser RPC dispatch;
  • cache the resolved policy;
  • report the underlying dependency failure in diagnostics;
  • add a test where the identity endpoint stalls while extension discovery and tab enumeration remain healthy.

Activity

  1. added
    bugSomething isn't working
    appIssues related to the Codex desktop app
    windows-osIssues related to Codex on Windows systems
    connectivityIssues involving networking or endpoint connectivity problems (disconnections)
    on Sep 12, 2026
  2. ggbonded commented on Sep 16, 2026

    @ggbonded
    No description provided.
  3. ChocoLZS commented on Sep 17, 2026

    @ChocoLZS

    Follow-up: isolated a second failure in the Statsig fetch bridge

    I reproduced this again on Windows with Codex CLI 0.150.1, Codex Desktop build 26.908.9136.0, @oai/browser-desktop 0.1.1, and the official ChatGPT Chrome extension.

    The original identity-lookup diagnosis remains relevant, but the current build has an additional failure after the identity path is reached:

    1. browser-service.mjs initializes Statsig with:

      networkOverrideFunc: (url, init) => runtime.fetch(url, init)
    2. The CUA nodeRepl.fetch path returns an HTTP 202 response for the Statsig request.

    3. Reading that response body fails with:

      nodeRepl.fetch response read failed
      
    4. Statsig ends in:

      loadingStatus = Ready
      success = false
      source = NoValues
      
    5. browser-service.mjs then emits the generic:

      Unable to load browser request-header policy. Retry the browser command.
      

    This makes the failure look like a Chrome/provider/browser-RPC problem, although the extension is already discoverable and the identity endpoint itself returns HTTP 200 through the browser session.

    Reversible local validation

    I kept the identity request on the CUA session fetch, but changed only the Statsig network override to use the bundled Node runtime's native fetch:

    - networkOverrideFunc: (url, init) => runtime.fetch(url, init)
    + networkOverrideFunc: (url, init) => globalThis.fetch(url, init)

    I also changed the three related hard-coded 10s guards to 30s for diagnosis:

    • Statsig initialization/update/Ck wait;
    • Statsig NetworkCore request timeout;
    • ChatGPT identity AbortSignal.timeout.

    With the native Statsig fetch path, the same runtime successfully received a usable Statsig response (HTTP 200, approximately 3.95 MB), the request-header gate was evaluated, and getState() returned Chrome plus its tabs with no errors. A clean post-restart check returned one Chrome extension browser, one Codex in-app browser, and errors: [].

    Suggested upstream fix

    • Fix nodeRepl.fetch response-body handling for the Statsig request path, including HTTP 202 responses.
    • Keep the request-header identity lookup bounded and failure-tolerant as described in the original report.
    • Avoid making browser discovery/tab RPC availability depend on optional Statsig policy telemetry.
    • Preserve the underlying network/body-read error instead of reducing it to NoValues and the generic policy error.

    No credentials or response bodies were included in this report. The local runtime was modified only as a reversible diagnostic workaround; the runtime package was not redistributed.

  4. yaseerali408-droid commented on Sep 21, 2026

    @yaseerali408-droid

    Follow-up: residual fixed ~21 s latency after the identity-policy workaround

    Reproduced on Windows with:

    • ChatGPT/Codex Desktop MSIX 26.915.4065.0
    • Computer Use bundle 26.915.31945
    • Microsoft Edge 153.0.4234.48
    • ChatGPT Edge extension 1.26.901.11451

    The bounded request-header identity workaround described in this issue restores browser discovery, tab enumeration, and tab claiming. However, a second fixed-latency failure remains:

    • A trivial read-only playwright.evaluate(() => document.title) against the IANA Example Domains page consistently takes about 21.08 seconds.
    • The same delay occurs for DOM snapshots and on TikTok Shop Seller Center, so it is not site-specific.
    • Browser/provider discovery and tab claiming succeed; the delay occurs during repeated tab-level CDP work.
    • An intermittent Debugger unattached state can also occur after a CUA kernel reset or navigation, but adding attach settle time and a detach/reattach recovery did not remove the fixed 21-second latency.

    Local source inspection points to per-command extension session preparation:

    executeCdp
      -> requireSessionTab
      -> rs(tabId)
      -> chrome.scripting.executeScript(...foreign-frame-monitor...)
    

    The helper wrapping the scripting calls has a default 1-second timeout. When the foreign-frame monitor cannot be confirmed/installed, the extension appears to retry this preparation across the multiple CDP operations used by one high-level browser action. Those repeated waits plausibly accumulate to the observed ~21 seconds.

    A reversible diagnostic change that made the monitor preparation non-blocking was prepared, but browser control was stopped at the user's request before a clean post-restart verification. Therefore this comment does not claim that change as a validated fix.

    Requested upstream changes:

    • Avoid blocking every CDP command on repeated frame-monitor preparation.
    • Cache or throttle a failed/unsupported monitor injection result for the active tab lease.
    • Preserve security behavior while allowing the monitor to finish asynchronously when it is not required for the current CDP operation.
    • Surface a specific diagnostic for scripting/monitor preparation timeouts.
    • Add a Windows Edge regression test covering repeated read-only evaluate/DOM calls after successful discovery and claim.
    • Continue treating the intermittent Debugger unattached path separately from the identity-policy and monitor-preparation latency.

    User impact: browser tasks repeatedly consume model time/quota while appearing disconnected or uncontrollable, even after reinstalling the extension and restarting Edge.

    This follow-up is posted at the affected user's request. Private URLs, account identifiers, local usernames/paths, process identifiers, raw logs, cookies, and credentials are omitted.

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 appbrowserbugSomething isn't workingconnectivityIssues involving networking or endpoint connectivity problems (disconnections)windows-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