Skip to content

Integration tests fail under NODE_USE_ENV_PROXY: the proxy-env scrub deletes NO_PROXY while Node's built-in proxy is active #2605

Description

@cliffhall

Problem

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.

Seen while gating #2591 (#2550):

Scope

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";
const srv = createServer((_, res) => res.end("ok"));
await new Promise((r) => srv.listen(0, "127.0.0.1", r));
const url = `http://127.0.0.1:${srv.address().port}/`;
await fetch(url);                                   // 200 ok
delete process.env.NO_PROXY; delete process.env.no_proxy;
await fetch(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.

Activity

  1. added this to the v2.10.0 milestone on Oct 5, 2026
  2. cliffhall commented on Oct 5, 2026

    @cliffhall
    MemberAuthor

    Triage: Priority Medium (total 7)

    • Severity 2: minor friction with an easy workaround (env -u NODE_USE_ENV_PROXY), but the mandatory gate is red in every sandbox session until applied
    • Urgency 3: wanted this milestone; every local:gate in the sandboxes hits it
    • Bonuses: +1 bug label, +1 milestoned (v2.10.0)

    Board: #28, Status Todo.

  3. added
    bugSomething isn't working
    v2Issues and PRs for v2
    on Oct 5, 2026
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

    bugSomething isn't workingv2Issues and PRs for v2

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions