-
-
Notifications
You must be signed in to change notification settings - Fork 33.5k
Description
Version
v24.3.0 (Other versions are also affected. See below.)
Platform
Darwin hood.local 24.6.0 Darwin Kernel Version 24.6.0: Mon Jul 14 11:30:29 PDT 2025; root:xnu-11417.140.69~1/RELEASE_ARM64_T6000 arm64
Also reported on Windows 11.
Subsystem
No response
What steps will reproduce the bug?
First, install jasmine@5.11.0. Then create runner.js as follows:
const Jasmine = require("jasmine");
const fs = require("fs");
(async () => {
const runner = new Jasmine();
runner.addSpecFile("./crash.spec.js");
runner.addReporter({
suiteDone: async () => {
console.log("\nAbout to crash!");
await fs.promises.readFile("./package.json");
},
});
await runner.execute();
})();
And create crash.spec.js as follows:
describe('a suite that crashes NodeJS', () => {
it('throws twice', async () => {
await new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error('foo'));
}, 0);
}).foo();
});
});
Finally, run node --unhandled-rejections=strict runner.js
.
I tried and failed to reduce this down to a simple code snippet with no dependencies. The user who reported it to me stated that it took them two days to reproduce it to this point.
How often does it reproduce? Is there a required condition?
Reproduces 100% of the time with (at least) 20.19.0, 22.14.0, 24.0.0, and 24.3.0. It's also been reported on >= 22.3.0. Does not reproduce with 20.0.0 or 22.0.0.
What is the expected behavior? Why is that the expected behavior?
Node should not crash. The script should run to completion and produce output like the following:
Randomized with seed 36538
Started
F
About to crash!
Failures:
1) a suite that crashes NodeJS throws twice
Message:
TypeError: (intermediate value).foo is not a function
Stack:
at UserContext.<anonymous> (/Users/steve/Downloads/no-zip/crash.spec.js:7:12)
at <Jasmine>
Suite error: top suite
Message:
Uncaught exception: Error: foo
Stack:
at Timeout._onTimeout (/Users/steve/Downloads/no-zip/crash.spec.js:5:24)
at listOnTimeout (node:internal/timers:573:17)
at process.processTimers (node:internal/timers:514:7)
Message:
Unhandled promise rejection: Error: foo
Stack:
at Timeout._onTimeout (/Users/steve/Downloads/no-zip/crash.spec.js:5:24)
at listOnTimeout (node:internal/timers:573:17)
at process.processTimers (node:internal/timers:514:7)
1 spec, 3 failures
Finished in 0.007 seconds
Randomized with seed 36538 (jasmine --random=true --seed=36538)
What do you see instead?
Randomized with seed 66384
Started
F
About to crash!
# node[9176]: void node::AsyncHooks::push_async_context(double, double, Local<Object>) at ../src/env.cc:130
# Assertion failed: (trigger_async_id) >= (-1)
----- Native stack trace -----
1: 0x10019f040 node::Assert(node::AssertionInfo const&) [/Users/steve/.nvm/versions/node/v24.3.0/bin/node]
2: 0x102236be0 node::AsyncHooks::push_async_context(double, double, v8::Local<v8::Object>) (.cold.2) [/Users/steve/.nvm/versions/node/v24.3.0/bin/node]
3: 0x1000dc85c node::AsyncHooks::grow_async_ids_stack() [/Users/steve/.nvm/versions/node/v24.3.0/bin/node]
4: 0x100098cb4 node::InternalCallbackScope::InternalCallbackScope(node::Environment*, v8::Local<v8::Object>, node::async_context const&, int, v8::Local<v8::Value>) [/Users/steve/.nvm/versions/node/v24.3.0/bin/node]
5: 0x100098da0 node::InternalCallbackScope::InternalCallbackScope(node::AsyncWrap*, int) [/Users/steve/.nvm/versions/node/v24.3.0/bin/node]
6: 0x100196cd4 node::fs::FSReqPromise<node::AliasedBufferBase<double, v8::Float64Array>>::Resolve(v8::Local<v8::Value>) [/Users/steve/.nvm/versions/node/v24.3.0/bin/node]
7: 0x1001a5850 node::fs::AfterStat(uv_fs_s*) [/Users/steve/.nvm/versions/node/v24.3.0/bin/node]
8: 0x1001973a8 node::MakeLibuvRequestCallback<uv_fs_s, void (*)(uv_fs_s*)>::Wrapper(uv_fs_s*) [/Users/steve/.nvm/versions/node/v24.3.0/bin/node]
9: 0x100fd12c4 uv__work_done [/Users/steve/.nvm/versions/node/v24.3.0/bin/node]
10: 0x100fd4ff4 uv__async_io [/Users/steve/.nvm/versions/node/v24.3.0/bin/node]
11: 0x100fe938c uv__io_poll [/Users/steve/.nvm/versions/node/v24.3.0/bin/node]
12: 0x100fd555c uv_run [/Users/steve/.nvm/versions/node/v24.3.0/bin/node]
13: 0x100099a98 node::SpinEventLoopInternal(node::Environment*) [/Users/steve/.nvm/versions/node/v24.3.0/bin/node]
14: 0x1001eb704 node::NodeMainInstance::Run() [/Users/steve/.nvm/versions/node/v24.3.0/bin/node]
15: 0x100159474 node::Start(int, char**) [/Users/steve/.nvm/versions/node/v24.3.0/bin/node]
16: 0x19fc1ab98 start [/usr/lib/dyld]
zsh: abort node --unhandled-rejections=strict runner.js
Additional information
If I replace await fs.promises.readFile("./package.json");
with await new Promise(resolve => setTimeout(resolve));
in runner.js, I sometimes get an early exit instead of a crash. It's easiest to see that if you patch node_modules/jasmine/lib/jasmine.js
as follows:
@@ -239,7 +239,7 @@
this.addMatchingSpecFiles(files);
}
- const prematureExitHandler = new ExitHandler(() => this.exit(4));
+ const prematureExitHandler = new ExitHandler(() => console.error('premature exit!'));
prematureExitHandler.install();
let overallResult;