Repository navigation
Codex Desktop Node REPL does not inherit proxy environment, causing nodeRepl.fetch and Chrome backend setup to hang on macOS #21713
Description
What issue are you seeing?
On macOS, Codex Desktop's built-in Node REPL runtime does not appear to inherit proxy environment variables, even after the variables are available to the app's shell subprocesses and to launchctl.
This causes nodeRepl.fetch() calls to OpenAI endpoints to hang, and it appears to block Chrome/Browser Use backend setup paths that depend on the Node REPL runtime.
Environment
Codex Desktop: 26.506.21252, build 2575
App-bundled codex-cli: 0.129.0-alpha.15
App-bundled Node: v24.14.0
Chrome plugin: openai-bundled/chrome/0.1.7
OS: macOS 15.2, arm64
Proxy endpoint: local HTTP proxy on 127.0.0.1
No account identifiers, emails, local usernames, or full local paths are included in this report.
What I configured
Proxy variables were configured at both the launchctl level and in Codex config for shell subprocesses:
HTTP_PROXY=http://127.0.0.1:<port>
HTTPS_PROXY=http://127.0.0.1:<port>
ALL_PROXY=http://127.0.0.1:<port>
NO_PROXY=localhost,127.0.0.1,::1
The same lowercase variants were also configured.
In ~/.codex/config.toml, shell_environment_policy.set contains the same values. After restarting Codex Desktop, shell subprocesses launched by Codex do receive these proxy variables.
Steps to reproduce
- On macOS, use a local HTTP proxy and configure proxy variables via
launchctl setenvand~/.codex/config.tomlshell_environment_policy.set. - Restart Codex Desktop.
- In the discovered Node REPL tool, inspect proxy-related environment variables:
const proxyKeys = [
"HTTP_PROXY", "HTTPS_PROXY", "ALL_PROXY", "NO_PROXY",
"http_proxy", "https_proxy", "all_proxy", "no_proxy",
];
const env = Object.fromEntries(proxyKeys.map((key) => [key, globalThis.process?.env?.[key] ?? null]));
nodeRepl.write(JSON.stringify(env, null, 2));- Attempt a fetch from the same Node REPL runtime:
await nodeRepl.fetch("https://chatgpt.com/backend-api/me");- Attempt Chrome plugin bootstrap or a lightweight Chrome browser-client call, such as listing open tabs.
Actual behavior
The built-in Node REPL runtime reports all proxy variables as null:
{
"HTTP_PROXY": null,
"HTTPS_PROXY": null,
"ALL_PROXY": null,
"NO_PROXY": null,
"http_proxy": null,
"https_proxy": null,
"all_proxy": null,
"no_proxy": null
}nodeRepl.fetch("https://chatgpt.com/backend-api/me") hangs until the Node REPL tool call times out and resets the kernel. A JavaScript AbortController timeout did not reliably interrupt the hang.
The Node REPL process environment, inspected from the host, appears to be a fixed allowlist containing CODEX_*, NODE_REPL_*, PATH, HOME, and a few standard variables, but not HTTP_PROXY, HTTPS_PROXY, ALL_PROXY, or lowercase variants.
Chrome plugin setup also times out, even though the local Chrome checks pass:
Google Chrome running: yes
Codex Chrome Extension installed and enabled: yes
Native messaging host manifest: valid
Control checks
The proxy itself is working:
- Shell subprocesses launched by Codex receive the proxy variables.
launchctl getenv HTTP_PROXYandlaunchctl getenv HTTPS_PROXYreturn the configured local proxy.- A separately launched app-bundled Node REPL process with the same proxy variables can complete
nodeRepl.fetch("https://chatgpt.com/backend-api/me")successfully. The response body was intentionally not logged.
This suggests the issue is specific to how Codex Desktop launches or sanitizes the built-in Node REPL runtime used by plugins/browser tooling.
Expected behavior
One of the following should happen:
- The built-in Node REPL runtime should inherit documented proxy configuration from Codex Desktop or from the shell environment policy.
- Or Codex Desktop should provide a documented config field for proxy variables used by built-in plugin runtimes such as Node REPL.
- Or OpenAI/ChatGPT network calls made during local browser backend setup should be isolated so they cannot hang local Chrome/Browser Use discovery.
At minimum, nodeRepl.fetch() and browser backend setup should fail with a bounded diagnostic instead of hanging until the tool call timeout resets the kernel.
Related issues
This looks related to, but more specific than, existing macOS proxy and Browser Use reports:
- Codex App GUI no longer works with Clash Verge macOS system proxy, while bundled TUI works with env proxy #13682
- Responses websocket is unstable on macOS launchd/system-proxy setups while HTTP works #14080
- fix(browser): Browser Use cannot connect to IAB from Node REPL on macOS #20678
Those issues describe Codex Desktop GUI proxy behavior and Browser Use/Chrome backend hangs. This report narrows one reproducible cause: the built-in Node REPL runtime does not receive proxy environment variables even after the app is restarted and shell subprocesses do receive them.
Activity
github-actions commentedon May 8, 2026
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
gezi-antony commentedon May 9, 2026
Adding the concrete user-facing scenario that led to this report:
The issue was first observed while trying to use the Codex Chrome plugin to control the user's existing Google Chrome session. The requested task was a normal authenticated-browser workflow: open a regular website in Chrome and proceed with the page interaction.
From the user's perspective, the Chrome plugin simply did not respond. Lightweight Chrome plugin operations such as listing open tabs / initializing the browser client never returned and eventually ended as a Node REPL JavaScript timeout:
This happened even after restarting Codex Desktop and Chrome, and after reinstalling the Chrome plugin. The local Chrome setup checks passed:
So the user-visible failure is not just that a manually invoked
nodeRepl.fetch()hangs. The practical failure is that the Chrome plugin appears unresponsive even though Chrome, the extension, and the native messaging host are present. The proxy inheritance problem in the built-in Node REPL is the lower-level symptom that seems to explain why the plugin bootstrap / ambient setup path cannot complete in this environment.EuDs63 commentedon Sep 2, 2026
I found a reproducible macOS workaround for this proxy-inheritance failure.
In my case, Chrome/extension/native-host checks passed, but page-level Chrome operations timed out because the bundled CUA launcher started the Node REPL child without the proxy environment variables. Passing them explicitly in the launcher's child spawn environment restored browser control:
The proxy values above are placeholders; this does not define a proxy by itself. They must match the proxy already used by the host environment.
After fully restarting Codex, a fresh Chrome tab could be opened and its accessibility tree read successfully. Before the change, Chrome tab/page operations timed out while extension discovery and the local Chrome checks still passed.
This is a local workaround, not an official fix. A future plugin update may replace the cached launcher, so the change may need to be reapplied until the child environment is handled by Codex itself.
gezi-antony commentedon Sep 2, 2026
Thanks @EuDs63 — this is useful evidence, and it also exposes an important scope distinction.
Live re-check on 2026-09-02:
NODE_USE_ENV_PROXY=1to the proxy environment that Codex itself prepares for child processes, keeps that key in the managed proxy allowlist, and has focused test coverage. I rerancargo test -p codex-network-proxy apply_proxy_env_overrides_sets_common_tool_varsagainstmain@8d32abcd; it passes.shell_environment_policyor inherited by its launcher.26.831.20005, build7524;codex-cli 0.152.0; Chrome plugin26.831.20005), proxy variables are present in shell subprocesses but absent fromlaunchctl. The current runtime no longer exposesprocessornodeRepl.fetch; neverthelesssetupBrowserRuntime()completed in 91 ms, Chrome selection succeeded, and opening a freshabout:blanktab plus reading its visible/accessibility DOM completed in 476 ms. So the original browser-setup failure is not reproducible on this current stack, but the old exact Node REPL probe is also no longer available.I think #21713 should remain distinct from #21704: this issue is the child launch-environment contract; #21704 is about bounding/failing open when optional ambient network work hangs.
To determine whether the newly reported case is (a) the already-fixed Node opt-in gap, (b) a remaining proxy allowlist propagation gap, or (c) the separate ambient timeout path, could you add the following redacted evidence?
set/unset, not values) forNODE_USE_ENV_PROXY,HTTP_PROXY,HTTPS_PROXY,ALL_PROXY, andNO_PROXYplus lowercase aliases.NODE_USE_ENV_PROXY=1only; both together.Suggested follow-up window: by 2026-09-09 if practical. The blocker is cleared once the version/artifact identity and the three-way outcome matrix identify which process boundary drops which key; without that evidence, the current-version result should be treated as non-reproducing rather than proof that the launcher gap is fixed everywhere.
If a product change is still needed, the invariant should be: every Codex-owned Node/browser child that is allowed outbound network gets the same effective host-prepared proxy route, through a narrow proxy-key allowlist including both case variants and
NODE_USE_ENV_PROXY; it should not broadly copyprocess.envor hard-code user proxy values. Regression coverage should include no proxy, Codex-managed proxy, user-configured proxy/bypass, and bounded Chrome setup failure.EuDs63 commentedon Sep 2, 2026
Basic identity only — not running the three-way outcome matrix.
~/.codex/plugins/cache/openai-bundled/unified-computer-use/26.831.20005/scripts/launch.mjs1c3df2b30b1c059c0c0997ef46178df1e6cc0ec53b030b01538da31d371d06a1gezi-antony commentedon Sep 2, 2026
Thanks — this confirms the workaround was tested on the same Codex Desktop
26.831.20005/ bundled CLI0.152.0generation. I’m treating it as a successful local workaround, not as validation of the stock runtime.Two evidence limits remain:
launch.mjs, so it cannot identify the stock artifact or the exact environment-policy delta;NODE_USE_ENV_PROXY, or from the separate ambient-timeout path in Chrome/browser-use setupAtlasRuntime can hang when ambient /backend-api/me probe does not complete #21704.No need to rerun the matrix if that is not practical. For the next reproduction on an unmodified install, the minimum useful evidence is the stock launcher artifact/SHA plus presence-only (
set/unset) parent-vs-child proxy keys; the three-way outcome matrix remains ideal.I’m keeping this open as evidence-blocked. A deterministic change in the public Codex-managed proxy path is not justified by the current result: #23905 already sets
NODE_USE_ENV_PROXY=1and retains it in the narrow managed-proxy allowlist. If stock evidence confirms a remaining gap, the fix should be at the actual Desktop/CUA child-launch boundary, forward only the effective proxy route keys (including bypass keys and case variants), and cover no-proxy, managed-proxy, user-configured proxy/bypass, plus bounded browser-setup failure. #21704 remains a separate fail-open/timeout concern.jinwukong commentedon Sep 8, 2026
Adding current-version evidence for the parent-to-child environment boundary discussed above.
Environment
26.901.51231, build81090.153.4v24.19.026.6.2, Apple Silicon / arm64152.0.7977.7626.901.512311.26.901.11451node_replMCP server and the Chrome extension backendThe final reproduction used native OpenAI model routing after restarting the desktop app. The host uses an existing HTTP(S) network proxy. App and browser-plugin code was not patched.
Observed behavior
Following the bundled Chrome skill's normal setup:
setupBrowserRuntime()succeeds.agent.browsers.get("chrome")succeeds and identifies the extension backend.await chrome.nameSession("Chrome diagnostic")fails after approximately 30 seconds.await chrome.tabs.list()attempt fails in the same way.Both failed operations report:
This was reproduced after the app restart. The failing sequence does not reach page creation or navigation, so page-level behavior has not been validated.
Parent/child environment, inspected from the host
These are presence-only observations from the desktop app-server process and an app-server-owned
node_replchild. No proxy values are included.node_replchildHTTP_PROXYHTTPS_PROXYALL_PROXYNO_PROXYhttp_proxyhttps_proxyall_proxyno_proxyNODE_USE_ENV_PROXYThe same proxy-variable absence was observed across the newly started
node_replprocesses. The table does not establish whether the failing fetch implementation needs the Node-specific opt-in.Installation and connectivity controls
The bundled diagnostics report Chrome running, the extension installed and enabled, and the native messaging manifest structurally valid with an existing host executable. Browser-client and browser-service scripts in the plugin cache match the copies shipped in the installed app byte-for-byte.
An unauthenticated HTTPS connectivity probe to an OpenAI endpoint timed out when forced direct, while using the host's existing proxy completed TLS and returned an HTTP response. This is only a connectivity comparison, not proof of authentication success or successful browser control.
Unmodified artifact fingerprints
Relative artifact names and SHA-256 values:
Evidence limits and requested behavior
This supports investigating the desktop-owned tool process's proxy configuration and the network-preflight error path. It does not yet prove the missing environment variables are the sole cause.
A minimal
mcp_servers.node_repl.env_varsforwarding configuration has been prepared and accepted by the config parser, but it has not yet been validated in a fresh tool process. No successful workaround or three-way proxy/Node-opt-in outcome matrix is claimed here.It would help to have a supported, durable way for this app-owned runtime to receive the effective host proxy and bypass settings through a narrow allowlist, with a diagnostic that distinguishes an outbound preflight failure from a Chrome-extension transport failure. This should preserve existing browser permission checks and avoid requiring edits to versioned plugin code.
Only sanitized technical observations are included; no raw logs, screenshots, private URLs, local usernames, account identifiers, or session identifiers are attached.
jinwukong commentedon Sep 8, 2026
Validation update for
26.901.51231/ bundled CLI0.153.4and thenode_repl-backed Chrome path:A fresh managed browser-tool process in another task has now completed this sequence successfully:
https://example.com/and read its rendered body.https://www.iana.org/help/example-domains.The desktop application remained running throughout this validation. Its original process and start time were unchanged. The fresh tool process had all eight standard proxy/bypass variables below, and an established connection from that process to the existing host proxy was observed during the test.
NODE_USE_ENV_PROXYwas unset in the successful tool process.The minimal forwarding configuration used for new tool processes is:
This is an addition to the existing server definition; its app-generated command, arguments, and environment entries remain intact. The proxy values already exist in the host environment. No launcher, app binary, native host, or browser-plugin patch is involved.
The validation was performed in the fresh managed task. Previously started tool processes retain their older startup environment, so this does not establish an in-place refresh of an existing failing tool process. It does show that restarting the entire desktop application was unnecessary to obtain a working process and verify the fix on this build.
Scope: basic Chrome page control only. Login, uploads, the
cua_replpath, and other versions were not tested. This is a verified user-configuration route for this reproduction, not a claim that the default launch-environment behavior has been fixed upstream.This update contains no proxy values, process IDs, timestamps, local paths, account identifiers, screenshots, or raw logs.
hi-max-wang commentedon Sep 8, 2026
@jinwukong Following up on your validation in #21713 (comment): the scenario I need to solve is macOS system HTTP/HTTPS proxy enabled, with TUN mode disabled. I want Codex browser tools to work in that setup without relying on TUN routing.
I tested a reduced two-variable variant in a fresh Desktop task on
26.901.51231/ build8109:This was the only custom MCP override. There was no custom
cua_repldefinition; it used the app-generated launcher. The previous explicit proxy environment entries and dynamic-launcher override were removed for the test.Observed results:
node_repl: browser runtime setup and documentation retrieval succeeded, butnameSession()hit the 30-second deadline.cua_repl: creating a Chrome tab forexample.comhit the 20-second deadline; creating an in-app Browser tab hit the 15-second deadline.Our running Desktop/app-server host had neither
HTTP_PROXYnorHTTPS_PROXY, and the new tool processes also lacked them.env_varsforwards existing process environment variables; it does not read macOS system proxy settings and turn them into those variables. Consequently, the snippet alone supplied no proxy values and did not solve this system-proxy-only setup. I reverted the test configuration.To distinguish the mechanisms clearly: having proxy environment variables in the host does not imply TUN mode is enabled. They can be populated independently, but that is an additional setup step which matters here.
Your comment explicitly states the host-environment prerequisite and excludes
cua_repl. Our test used only two variables rather than your full eight-variable configuration, so these results do not disprove your scoped success. They do show that the snippet alone cannot replace the workaround in #42454 for our setup.Could you document how you populated the Desktop/app-server host proxy environment, and whether your successful test was performed with TUN disabled? A reproducible host-environment setup for the non-TUN case would make this actionable.
jinwukong commentedon Sep 8, 2026
Persistence update: a subsequent normal desktop restart on
26.901.51231regenerated themcp_servers.node_replblock and removed the addedenv_varslist. The newly started tool processes again lacked the proxy variables.The startup configuration-sync path uses
config/batchWritewithmergeStrategy: "replace"for the generated MCP block. This explains why the earlier successful runtime test did not establish a durable desktop configuration fix.I also completed an independent acceptance test using the official CLI and a separate named configuration-profile layer containing the same proxy-variable forwarding list. Opening and reading a fresh page, clicking through, reading the destination, navigating back, taking a screenshot, and closing the test tab all passed. Normal sandbox and automatic-review handling remained enabled. A configuration-layer test also preserved the forwarding list when an app-generated transport definition was overlaid.
The distinction is now clear: the forwarding settings are functional, but storing them only in the app-regenerated user block is not restart-stable. This is related to the generated-configuration overwrite problem in #42454, and the affected surface here is
node_repl.A durable, documented user override for generated runtime environments is still needed. System managed defaults are a documented separate layer, but I have not deployed or validated that placement yet and am not presenting it as a tested desktop workaround.
No private paths, proxy values, account identifiers, process IDs, screenshots, or raw logs are included.
KX76 commentedon Sep 13, 2026
Adding a Windows reproduction that appears consistent with this issue. The proxy endpoint is reachable, but the browser-tool runtime makes outbound connections that fail before it can enumerate browser tabs.
Environment
26.908.4834.026.908.408341.26.901.11451, installed and enabled according to the bundled diagnostic127.0.0.1:7897Reproduction
Start the local HTTP proxy.
Fully exit Codex Desktop and launch it from a
.cmdfile that sets:Open Edge or Chrome with the browser extension enabled.
Ask Codex to enumerate the open browser tabs or read an already-open page.
Actual behavior
Browser selection can return a browser name/ID, but subsequent discovery or tab enumeration fails after approximately 21 seconds:
The failure happens before page content is read. Retrying with Chrome instead of Edge, and resetting the JavaScript tool session, did not resolve it.
Diagnostic observations
netstatshowed the bundlednode_repl.exemaking outbound TCP connections to remote port 443 that remained inSYN_SENT.chatgpt.comandab.chatgpt.comin the Windows DNS cache. The failing sockets targeted the remote addresses rather than the configured local HTTP proxy endpoint.[mcp_servers.node_repl.env]section in the user configuration. The TOML was validated and the values were read back successfully. After fully restarting Codex Desktop, those entries were absent again, and the browser-tool failure persisted. This did not provide a persistent workaround.Scope and uncertainty
These observations suggest a proxy propagation problem in the managed browser-tool runtime. I have not directly captured its complete process environment or established why those requests do not use the local HTTP proxy.
A separate native-host registration diagnostic also reported an issue on this machine, so I am not claiming that all extension transport checks pass or that proxy propagation is necessarily the only problem. However, the captured OpenAI connection timeouts occur in the tool runtime and reproduce with both browsers.
Would it be possible to preserve proxy settings for the managed Node REPL runtime, or provide a supported per-runtime proxy configuration that survives Desktop startup? A diagnostic identifying the failing network stage would also make this easier to troubleshoot.
No account identifiers, credentials, local usernames, absolute filesystem paths, or raw network addresses are included above, apart from the loopback proxy endpoint.
gezi-antony commentedon Sep 13, 2026
Thanks KX76 for separating the direct-connection observation from the native-host diagnostic. Together with jinwukong's September 8 results, this advances the evidence beyond my September 2 assessment.
What is established, and what is not
node_repltest completed real page operations in a fresh process after forwarding the existing host proxy/bypass variables, withNODE_USE_ENV_PROXYunset. The restart follow-up then found that Desktop removedenv_vars. This supports both a functional forwarding route on that build and a separate persistence defect; it is not an upstream fix.New read-only implementation evidence
I inspected the installed macOS Desktop package
26.903.71938/ build8576. This is a separate artifact inspection, not a reproduction of KX76's newer Windows build:config/batchWritewithmergeStrategy: replace; the inspected path does not merge the existing user block's proxyenv/env_varsinto it.envandenv_varsfrom that newly generated Node definition into the plugin manifest. The inspected materializedcua_replmanifest hasenv_vars: []and none of the eight standard proxy/bypass keys.launch.mjsitself spreadsprocess.envinto the spawned child. Adding the same spread again would not repair variables already missing before the launcher starts.Artifact identifiers:
main-Bkkz0ENj.jsSHA-256037076973c753515ef4329aa493f1072902cc638cbbcec788d81c87f392342f2;launch.mjsSHA-256a50b66879f7b72e45ab6fbaad77eff14a87680a946135f410c121b9b166a2597. Installed files and live configuration were not modified, and no restart or end-to-end browser recovery is claimed.The public source is consistent with this boundary: MCP constructs a selected environment, then launches with
env_clear().envs(...). The documentedenv_varssetting forwards existing environment variables; it does not turn OS system-proxy settings into variables. Generic whole-table replacement also has an explicit existing test.Focused next step
The candidate product fix belongs at the Desktop-generated runtime/user-override boundary, shared with #42454: define a supported, restart-stable proxy environment overlay while keeping executable paths, native pipes, session-specific fields, and permission policy app-owned. Its contract must preserve explicit user changes and deletions, proxy/bypass precedence and case handling, and the distinction between local and remote runtimes. Merely changing generic
replacetoupsert, preserving every stale environment field, or enabling Node proxy handling unconditionally is not a sufficient fix.Acceptance should cover no-proxy and proxy-required setups, absent parent variables, restart/update persistence, removing an override, refreshed app-owned fields, and actual page operations. Network/preflight errors need bounded stage-specific diagnostics while preserving authorization checks; native-host registration and debugger attachment should remain separately identifiable.
I am keeping this issue open. The next upstream action is to define and implement that generated-runtime override contract; this is now a focused implementation boundary, not a request to repeat the earlier full matrix before acknowledging configuration loss. In accordance with the repository's current contribution policy, I am recording the RCA here rather than opening an external code PR.
spark4862 commentedon Oct 3, 2026
macOS follow-up on Desktop 26.930.21537: CUA proxy environment is still missing
Reproduced on 2026-10-03 with macOS 15.8.1 / Apple Silicon, Desktop 26.930.21537 (build 12776), Edge 154.0.4258.48, official Edge extension 1.26.901.11451, browser bundle 26.930.21537, and bundled CUA Node v24.21.0.
Extension discovery and browser selection succeed.
browser.user.openTabs()fails after 30,012 ms withnodeRepl.fetch request failed.The relevant live CUA launcher and its Node REPL child both lack HTTP_PROXY, HTTPS_PROXY, lowercase variants, NO_PROXY, and NODE_USE_ENV_PROXY. During reproduction, the Node REPL assigned to the affected chat opens direct public TCP connections matching local ChatGPT DNS results. These remain in SYN_SENT. Meanwhile, the main application runtime has established connections to the existing loopback HTTP proxy.
A separate transport-only control using the same bundled Node binary and the same identity URL times out after the test's 8-second bound with default fetch. With the existing proxy environment and
--use-env-proxy, it receives HTTP 403 in 359 ms. This unauthenticated control demonstrates a transport difference; it does not demonstrate successful session authentication.Local source inspection confirms that the CUA launcher forwards its current environment without adding proxy settings, and the browser service has an identity-dependent request-header decision before some extension RPCs. The proxy inheritance failure is established; end-to-end recovery with the existing proxy client's TUN mode is documented in the verification below. We do not claim a Statsig payload-size failure or attribute the separate IAB route warning to this cause.
Reinstalling the extension, restarting Edge, and restarting the desktop app did not resolve it. There is now one official Edge extension instance, and the running native host uses the current bundle.
Please provide a supported proxy/environment configuration for the managed CUA runtime and preserve it across app restarts and updates. Please also expose the failed endpoint and underlying transport error instead of only the generic fetch failure.
This report excludes usernames, email addresses, local paths, process IDs, IP addresses, proxy provider details, task/extension-instance identifiers, credentials, browsing content, screenshots, and raw logs. No runtime or security-policy patch was applied.
Verification after enabling the existing proxy client's TUN mode
With TUN active, the same selected Edge browser and the same CUA session returned 24 tabs in 5,249 ms. Claiming the existing requested tab, reading its DOM, and navigating its visible UI succeeded. No desktop restart, source patch, policy bypass, credential change, or additional extension installation was used for this verification. This establishes an end-to-end local network workaround for this reproduction. It does not establish that the upstream proxy-environment defect is fixed.