You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Integration tests fail under NODE_USE_ENV_PROXY: the proxy-env scrub deletes NO_PROXY while Node's built-in proxy is active #2605
With NODE_USE_ENV_PROXY=1 in the environment, npm run local:gate fails coverage:web with 18 integration-test failures unrelated to any diff. All of them are Proxy response (502) !== 200 when HTTP Tunneling / UND_ERR_ABORTED on requests to the tests' own 127.0.0.1 servers. The Docker sandboxes these sessions run in set exactly that, alongside HTTP(S)_PROXY and NO_PROXY=localhost,127.0.0.1,::1,gateway.docker.internal. The full gate is red there on every run, regardless of the change under test.
This failure has been seen only inside a Docker sandbox, where the environment sets NODE_USE_ENV_PROXY=1 along with an HTTP(S)_PROXY that can't reach the sandbox's own loopback. It has not been seen when running Node and Claude Code directly on the host, where NODE_USE_ENV_PROXY is normally unset and the tests' proxy-variable scrub has nothing to interact with. A host would hit it only if someone set NODE_USE_ENV_PROXY=1 themselves (for example, behind a corporate proxy).
Cause
Both suites deliberately delete HTTP_PROXY/http_proxy/HTTPS_PROXY/https_proxy/NO_PROXY/no_proxy from process.env in beforeAll. That isolates the app's memoized undici EnvHttpProxyAgent (#2067) from the ambient proxy. They don't touch NODE_USE_ENV_PROXY, which turns on Node's built-in env-proxy support for the whole process. That built-in support captures the proxy URL at startup but re-reads NO_PROXY per request. Once the suite deletes NO_PROXY, nothing exempts loopback, and the test's own fetch to 127.0.0.1 is tunnelled to the sandbox proxy, which can't reach the sandbox's loopback and answers 502.
Minimal reproduction (Node 22.22, no repo code):
import{createServer}from"node:http";constsrv=createServer((_,res)=>res.end("ok"));awaitnewPromise((r)=>srv.listen(0,"127.0.0.1",r));consturl=`http://127.0.0.1:${srv.address().port}/`;awaitfetch(url);// 200 okdeleteprocess.env.NO_PROXY;deleteprocess.env.no_proxy;awaitfetch(url);// NODE_USE_ENV_PROXY=1: "Request was cancelled."
NO_PROXY intact
NO_PROXY deleted
NODE_USE_ENV_PROXY=1
200 ok
FAILED: Request was cancelled.
unset
200 ok
200 ok
Running the same three files with env -u NODE_USE_ENV_PROXY passes 107 of 108; the remaining failure is the separate flake #2580.
Proposed fix
Make the test runner independent of Node's built-in proxy: remove NODE_USE_ENV_PROXY from process.env in the shared Vitest config (vitest.shared.mts) before any forks-pool worker spawns, since workers inherit the parent's env at spawn time. Add a comment saying why. It should live in the repo rather than in per-sandbox config (/etc/sandbox-persistent.sh) or host sbx settings, because a repo fix:
covers every sandbox and every developer machine that sets the variable, and survives Node versions where the built-in support is on by default;
doesn't change Node's proxying for anything else in the sandbox, where it may be what lets other Node tools reach the internet.
Why not the alternatives:
Restoring NO_PROXY with loopback instead of deleting it would break the Inspector proxy issue #2067 test, which deliberately routes a request to a 127.0.0.1 upstream through a 127.0.0.1 test proxy.
The app's real outbound proxying is unaffected, because it uses userland undici's EnvHttpProxyAgent, not Node's built-in support (see clients/cli/README.md, Inspector proxy issue #2067). npm reads the proxy variables itself, so npx/pack:verify registry access is unchanged too.
Acceptance
npm run local:gate passes in an environment with NODE_USE_ENV_PROXY=1 and an unreachable HTTP(S)_PROXY (the sandbox shape), with no per-shell workaround.
Check whether the later gate stages (smokes, smoke:web:firefox, Storybook) are also affected under that shape; they never ran in the observed failure because the chain stopped at coverage:web. Cover them if so.
A guard or test that would catch the regression, e.g. asserting NODE_USE_ENV_PROXY is absent inside a test worker.
Problem
With
NODE_USE_ENV_PROXY=1in the environment,npm run local:gatefailscoverage:webwith 18 integration-test failures unrelated to any diff. All of them areProxy response (502) !== 200 when HTTP Tunneling/UND_ERR_ABORTEDon requests to the tests' own127.0.0.1servers. The Docker sandboxes these sessions run in set exactly that, alongsideHTTP(S)_PROXYandNO_PROXY=localhost,127.0.0.1,::1,gateway.docker.internal. The full gate is red there on every run, regardless of the change under test.Seen while gating #2591 (#2550):
src/test/integration/mcp/remote/server-extra-coverage.test.ts: the/api/fetchblock (forwarding, 400/500/504 paths, the OAuth path has no request timeouts outside token revocation #2319 deadline and cancellation tests, the Inspector proxy issue #2067HTTP_PROXYrouting test)src/test/integration/mcp/node/transport.test.ts:createTransportheader/onFetchRequest/onFetchResponseBodytestssrc/test/integration/mcp/inspectorClient-timeout-diagnostics.test.tsScope
This failure has been seen only inside a Docker sandbox, where the environment sets
NODE_USE_ENV_PROXY=1along with anHTTP(S)_PROXYthat can't reach the sandbox's own loopback. It has not been seen when running Node and Claude Code directly on the host, whereNODE_USE_ENV_PROXYis normally unset and the tests' proxy-variable scrub has nothing to interact with. A host would hit it only if someone setNODE_USE_ENV_PROXY=1themselves (for example, behind a corporate proxy).Cause
Both suites deliberately delete
HTTP_PROXY/http_proxy/HTTPS_PROXY/https_proxy/NO_PROXY/no_proxyfromprocess.envinbeforeAll. That isolates the app's memoized undiciEnvHttpProxyAgent(#2067) from the ambient proxy. They don't touchNODE_USE_ENV_PROXY, which turns on Node's built-in env-proxy support for the whole process. That built-in support captures the proxy URL at startup but re-readsNO_PROXYper request. Once the suite deletesNO_PROXY, nothing exempts loopback, and the test's ownfetchto127.0.0.1is tunnelled to the sandbox proxy, which can't reach the sandbox's loopback and answers 502.Minimal reproduction (Node 22.22, no repo code):
NO_PROXYintactNO_PROXYdeletedNODE_USE_ENV_PROXY=1Running the same three files with
env -u NODE_USE_ENV_PROXYpasses 107 of 108; the remaining failure is the separate flake #2580.Proposed fix
Make the test runner independent of Node's built-in proxy: remove
NODE_USE_ENV_PROXYfromprocess.envin the shared Vitest config (vitest.shared.mts) before any forks-pool worker spawns, since workers inherit the parent's env at spawn time. Add a comment saying why. It should live in the repo rather than in per-sandbox config (/etc/sandbox-persistent.sh) or hostsbxsettings, because a repo fix:Why not the alternatives:
NO_PROXYwith loopback instead of deleting it would break the Inspector proxy issue #2067 test, which deliberately routes a request to a127.0.0.1upstream through a127.0.0.1test proxy.EnvHttpProxyAgent, not Node's built-in support (seeclients/cli/README.md, Inspector proxy issue #2067). npm reads the proxy variables itself, sonpx/pack:verifyregistry access is unchanged too.Acceptance
npm run local:gatepasses in an environment withNODE_USE_ENV_PROXY=1and an unreachableHTTP(S)_PROXY(the sandbox shape), with no per-shell workaround.smoke:web:firefox, Storybook) are also affected under that shape; they never ran in the observed failure because the chain stopped atcoverage:web. Cover them if so.NODE_USE_ENV_PROXYis absent inside a test worker.