test_gap_net_connect_bound_value regressed pass → parity_fail on main (red in every recent sweep's gap-suite (3), and the last gap regression standing after #8464): net.connect(port, host, cb) returns undefined (then TypeError: Cannot read properties of undefined (reading 'on')), while typeof net.connect still says function and net.createServer works.
Bisected to #8343 (6674f59) — its second casualty after #8447. The test uses Node's own ESM idiom:
import { createRequire } from "node:module";
const require = createRequire(import.meta.url);
const net = require("net");
Pre-#8343, the destructuring fast path rewrote const net = require("net") into the static native-module namespace binding unconditionally (ignoring the local require) — so net.connect compiled to the static codegen table and worked. #8343's require_is_shadowed_by_local guard (correct for the CJS wrap's synthetic function require(...)) also fires for this idiom, so the call now flows to the runtime createRequire namespace, where ("net","connect")'s dispatch arm routes through JS_NATIVE_HTTP_DISPATCH — which is null unless the external-http-server-pump stdlib feature is compiled in and registered, and returns undefined when null. The gap-suite build never has that wiring, and neither do default-feature builds.
Fix direction: a local require initialized from createRequire(...) (imported createRequire, including renames) is Node-semantically the real module-scoped require — for builtin specifiers it returns exactly the builtin namespace. Mark that binding as createRequire-backed at declaration and exempt it from require_is_shadowed_by_local, restoring the pre-#8343 static namespace path for this idiom while keeping #8343's shadowing for the CJS wrap's synthetic function require (a real function with a body). The turbopack/mysql2 shape in the test header is exactly this idiom, so the regression bites real bundled apps, not just the gap suite.
Separately worth noting (not fixed here): the runtime ("net","connect") arm silently returns undefined when JS_NATIVE_HTTP_DISPATCH is null — a throw ("net.connect requires the http server pump") would have turned this silent evaporation into a diagnosable error.
test_gap_net_connect_bound_valueregressedpass → parity_failon main (red in every recent sweep's gap-suite (3), and the last gap regression standing after #8464):net.connect(port, host, cb)returnsundefined(thenTypeError: Cannot read properties of undefined (reading 'on')), whiletypeof net.connectstill saysfunctionandnet.createServerworks.Bisected to #8343 (6674f59) — its second casualty after #8447. The test uses Node's own ESM idiom:
Pre-#8343, the destructuring fast path rewrote
const net = require("net")into the static native-module namespace binding unconditionally (ignoring the localrequire) — sonet.connectcompiled to the static codegen table and worked. #8343'srequire_is_shadowed_by_localguard (correct for the CJS wrap's syntheticfunction require(...)) also fires for this idiom, so the call now flows to the runtime createRequire namespace, where("net","connect")'s dispatch arm routes throughJS_NATIVE_HTTP_DISPATCH— which is null unless theexternal-http-server-pumpstdlib feature is compiled in and registered, and returnsundefinedwhen null. The gap-suite build never has that wiring, and neither do default-feature builds.Fix direction: a local
requireinitialized fromcreateRequire(...)(importedcreateRequire, including renames) is Node-semantically the real module-scoped require — for builtin specifiers it returns exactly the builtin namespace. Mark that binding as createRequire-backed at declaration and exempt it fromrequire_is_shadowed_by_local, restoring the pre-#8343 static namespace path for this idiom while keeping #8343's shadowing for the CJS wrap's syntheticfunction require(a real function with a body). The turbopack/mysql2 shape in the test header is exactly this idiom, so the regression bites real bundled apps, not just the gap suite.Separately worth noting (not fixed here): the runtime
("net","connect")arm silently returnsundefinedwhenJS_NATIVE_HTTP_DISPATCHis null — a throw ("net.connect requires the http server pump") would have turned this silent evaporation into a diagnosable error.