Repository navigation
[Windows][Desktop] Browser tab RPCs block on unbounded request-header identity lookup #45014
Description
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-desktop0.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;
getInforeaches the extension;- the native host is running;
openTabsand 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?
- Run Codex Desktop
26.903.9818.0on Windows. - Enable the official ChatGPT browser extension in Edge.
- Verify that Codex discovers Edge as an extension-backed browser.
- In a fresh local task, select Edge and call
browser.user.openTabs()or an equivalent tab-list operation. - Observe that the call waits roughly 21 seconds and fails with
nodeRepl.fetch request failed. - 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 --checkpasses; - 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
github-actions commentedon Sep 12, 2026
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
ggbonded commentedon Sep 16, 2026
ChocoLZS commentedon Sep 17, 2026
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 build26.908.9136.0,@oai/browser-desktop0.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:
browser-service.mjsinitializes Statsig with:The CUA
nodeRepl.fetchpath returns an HTTP202response for the Statsig request.Reading that response body fails with:
Statsig ends in:
browser-service.mjsthen emits the generic: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:
I also changed the three related hard-coded
10sguards to30sfor diagnosis:NetworkCorerequest timeout;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, anderrors: [].Suggested upstream fix
nodeRepl.fetchresponse-body handling for the Statsig request path, including HTTP 202 responses.NoValuesand 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.
yaseerali408-droid commentedon Sep 21, 2026
Follow-up: residual fixed ~21 s latency after the identity-policy workaround
Reproduced on Windows with:
26.915.4065.026.915.31945153.0.4234.481.26.901.11451The bounded request-header identity workaround described in this issue restores browser discovery, tab enumeration, and tab claiming. However, a second fixed-latency failure remains:
playwright.evaluate(() => document.title)against the IANA Example Domains page consistently takes about 21.08 seconds.Debugger unattachedstate 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:
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:
Debugger unattachedpath 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.