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
domain AsyncHook TypeError: Cannot read properties of undefined (again) #40999
$ node --abort-on-uncaught-exception eval.js
TypeError: Cannot read properties of undefined (reading 'enter')
at AsyncHook.before (node:domain:97:20)
at emitHook (node:internal/async_hooks:237:38)
at emitBeforeScript (node:internal/async_hooks:503:5)
at promiseBeforeHook (node:internal/async_hooks:347:3)
1: 0xb02ec0 node::Abort() [node]
2: 0xb76589 [node]
3: 0xd4a18e [node]
4: 0xd4b5af v8::internal::Builtin_HandleApiCall(int, unsigned long*, v8::internal::Isolate*) [node]
5: 0x15e7959 [node]
Aborted (core dumped)
How often does it reproduce? Is there a required condition?
The script runs without fault in node v12.22.7, but provokes failure reliably on stock node (as delivered by nvm) in versions:
14.18.0
16.13.0
17.1.0
Note that failure is only sporadic if the number of evaluations scheduled (the upper bound of the for loop) is cut to, say, 100 or 500, and the script runs without fault when the number is set to something very small like 10.
What is the expected behavior?
No failure, as in node v12.x.
What do you see instead?
No response
Additional information
A very similar-looking issue was reported in #30122, but the script provided here does work as expected in the failing version of node reported there (12.13.0).
As far as I can tell it's less an async_hooks issue and more an issue with domains, vm contexts, and gc timing. I don't really have the time to investigate properly right now though. 😕
Having seen this failure a couple of times in production (and not wanting to use node v12.x pending an actual fix), I tinkered a bit, and found what seems like a reliable workaround: setting a dummy timeout prior to using any newly-created domain. Here's a revision of the minimal repro from the original issue description, with such a timeout added:
Whether this works because it's helping the program dodge a timing bug or not is definitely above my pay grade here, but maybe someone will find it helpful.
(Interestingly, v12 runs the above in half the time as v16. Obviously it's a pathological bit of code, but it seems notable.)
This is creating a domain within a promise, then running a function created using the VM2 module inside of the domain. This consistently reproduces for me even with 1 or 2 invocations, usually on the first invocation but every so often it will continue on for a bit before failing. Wrapping each domain.run call with a setTimeout(0) or a nextTick does not seem to help as suggested above.
Activity
targos commentedon Nov 29, 2021
@nodejs/async_hooks
vdeturckheim commentedon Dec 1, 2021
It seems to be a recurring issue of vm and async hooks not playing well together. I believe @Qard noticed it too.
Qard commentedon Dec 9, 2021
As far as I can tell it's less an async_hooks issue and more an issue with domains, vm contexts, and gc timing. I don't really have the time to investigate properly right now though. 😕
cemerick commentedon Dec 29, 2021
Having seen this failure a couple of times in production (and not wanting to use node v12.x pending an actual fix), I tinkered a bit, and found what seems like a reliable workaround: setting a dummy timeout prior to using any newly-created domain. Here's a revision of the minimal repro from the original issue description, with such a timeout added:
Whether this works because it's helping the program dodge a timing bug or not is definitely above my pay grade here, but maybe someone will find it helpful.
(Interestingly, v12 runs the above in half the time as v16. Obviously it's a pathological bit of code, but it seems notable.)
bagelbits commentedon Mar 8, 2022
I've noticed this is not an issue in 14.15, but is still an issue in 14.19.
bagelbits commentedon Mar 8, 2022
Anecdotally, this issue is also not present in 14.17.
yocontra commentedon Jun 5, 2022
Chiming in - I get this issue consistently with code like this on the latest node 16:
This is creating a domain within a promise, then running a function created using the VM2 module inside of the domain. This consistently reproduces for me even with 1 or 2 invocations, usually on the first invocation but every so often it will continue on for a bit before failing. Wrapping each
domain.runcall with a setTimeout(0) or a nextTick does not seem to help as suggested above.