Importing `internal/deps/v8/tools/*` crashes
Version
v26.0.0-pre (main, 4451309e99e37da7d4b44b5fb136db1c6a1dea90)
Platform
Linux tumba 6.17.9-gentoo-yuran #1 SMP Thu Nov 27 04:38:45 +08 2025 x86_64 Intel(R) Core(TM)2 Quad CPU Q8200 @ 2.33GHz GenuineIntel GNU/Linux
Subsystem
internal/deps/v8/tools/
What steps will reproduce the bug?
$ ./node --expose-internals --eval "require('internal/deps/v8/tools/arguments')"
$ ./node --expose-internals --eval "import('internal/deps/v8/tools/arguments')"
How often does it reproduce? Is there a required condition?
Always on main.
On v24.11.1 attempt to import these throws SyntaxError.
What is the expected behavior? Why is that the expected behavior?
No crash.
What do you see instead?
$ ./node --expose-internals --eval "require('internal/deps/v8/tools/arguments')"
# ./node[7423]: v8::MaybeLocal<v8::Function> node::builtins::BuiltinLoader::LookupAndCompileFunction(v8::Local<v8::Context>, const char*, node::Realm*) at ../src/node_builtins.cc:466
# Assertion failed: data->IsValue()
----- Native stack trace -----
1: 0x5634e39df9c5 node::Assert(node::AssertionInfo const&) [./node]
2: 0x5634e39a8dcc node::builtins::BuiltinLoader::LookupAndCompileFunction(v8::Local<v8::Context>, char const*, node::Realm*) [./node]
3: 0x5634e39a8eeb node::builtins::BuiltinLoader::CompileFunction(v8::FunctionCallbackInfo<v8::Value> const&) [./node]
4: 0x7f774bdcfb4d
----- JavaScript stack trace -----
1: compileForInternalLoader (node:internal/bootstrap/realm:395:18)
2: compileForPublicLoader (node:internal/bootstrap/realm:337:10)
3: loadBuiltinModule (node:internal/modules/helpers:125:7)
4: loadBuiltinWithHooks (node:internal/modules/cjs/loader:1187:15)
5: node:internal/modules/cjs/loader:1262:20
6: traceSync (node:diagnostics_channel:328:14)
7: wrapModuleLoad (node:internal/modules/cjs/loader:245:24)
8: node:internal/modules/cjs/loader:1503:12
9: require (node:internal/modules/helpers:152:16)
10: [eval]:1:1
Aborted ./node --expose-internals --eval "require('internal/deps/v8/tools/arguments')"
$ ./node --expose-internals --eval "import('internal/deps/v8/tools/arguments')"
# ./node[7451]: v8::MaybeLocal<v8::Function> node::builtins::BuiltinLoader::LookupAndCompileFunction(v8::Local<v8::Context>, const char*, node::Realm*) at ../src/node_builtins.cc:466
# Assertion failed: data->IsValue()
----- Native stack trace -----
1: 0x559ec33df9c5 node::Assert(node::AssertionInfo const&) [./node]
2: 0x559ec33a8dcc node::builtins::BuiltinLoader::LookupAndCompileFunction(v8::Local<v8::Context>, char const*, node::Realm*) [./node]
3: 0x559ec33a8eeb node::builtins::BuiltinLoader::CompileFunction(v8::FunctionCallbackInfo<v8::Value> const&) [./node]
4: 0x7f758bdcfb4d
----- JavaScript stack trace -----
1: compileForInternalLoader (node:internal/bootstrap/realm:395:18)
2: compileForPublicLoader (node:internal/bootstrap/realm:337:10)
3: loadBuiltinModule (node:internal/modules/helpers:125:7)
4: builtinStrategy (node:internal/modules/esm/translators:465:18)
5: #translate (node:internal/modules/esm/loader:467:20)
6: afterLoad (node:internal/modules/esm/loader:523:29)
7: loadAndTranslate (node:internal/modules/esm/loader:528:12)
8: #getOrCreateModuleJobAfterResolve (node:internal/modules/esm/loader:565:36)
9: afterResolve (node:internal/modules/esm/loader:618:52)
10: getOrCreateModuleJob (node:internal/modules/esm/loader:624:12)
Aborted ./node --expose-internals --eval "import('internal/deps/v8/tools/arguments')"
Additional information
await Promise.allSettled(require('node:module').builtinModules.filter(name => !name.startsWith('internal/deps/v8/tools/')).map(name => import(name))) with --expose-internals throws errors and effectively makes process unusable, but does not abort.
/cc @joyeecheung
Is there a reason that it should support user land importing? It seems fine to crash as a form of saying "not supported" instead of bothering to add complexity to make it throw syntax errors (which is still not usable).
IMHO crashing should never happen, even with internals being exposed. Maybe it's feasible to throw ERR_INTERNAL_ASSERTION before attempting to actually load them? Or maybe it would make sense to exclude non-importable modules from module.builtinModules and let import throw MODULE_NOT_FOUND?