Repository navigation
ObjectWrap cleanup hooks break pre-built addons on Node.js 26.0.0-26.3.1 runtimes #65262
Copy link
Copy link
Open
Labels
addonsIssues and PRs related to native addons.Issues and PRs related to native addons.c++Issues and PRs that require attention from people who are familiar with C++.Issues and PRs that require attention from people who are familiar with C++.
Description
Activity
- addedaddonsIssues and PRs related to native addons.Issues and PRs related to native addons.c++Issues and PRs that require attention from people who are familiar with C++.Issues and PRs that require attention from people who are familiar with C++.
on Aug 13, 2026 The same assertion exists on the 24.x LTS line, but there it does not need a header/runtime
mismatch: headers and runtime both at 24.19.0 abort deterministically.Using your reproducer unchanged, on Darwin 25.5.0 arm64 with the official tarballs, 5/5 runs
per cell:hdr \ rt 24.18.1 24.19.0 24.18.1 ok ok 24.19.0 crash crash # node[52504]: void node::RemoveEnvironmentCleanupHook(Isolate *, CleanupHook, void *) at ../src/api/hooks.cc:142 # Assertion failed: (env) != nullptr 4: node::ObjectWrap::RemoveCleanupHook() [addon-hdr-24.19.0.node] 5: node::ObjectWrap::~ObjectWrap() [addon-hdr-24.19.0.node]The reason the diagonal fails there is that 24.19.0 got the
RemoveCleanupHook()half of the
change (#63642) but not the1723773dhalf that you identified, so no 24.x runtime tolerates
it:$ curl -s https://raw.githubusercontent.com/nodejs/node/v24.19.0/src/node_object_wrap.h | grep -c 'RemoveCleanupHook()' 2 $ curl -s https://raw.githubusercontent.com/nodejs/node/v24.19.0/src/api/hooks.cc | grep -c CleanupHookThunk 0
v24.x-stagingis in the same state today. Filed separately as #65446 since the fix
there is a backport rather than a runtime upgrade, but happy for it to be folded into this
issue if you would rather keep it in one place.- added 2 commits that reference this issue
on Aug 28, 2026 - added a commit that references this issue
on Sep 4, 2026 - added 2 commits that reference this issue
on Sep 7, 2026 - added a commit that references this issue
on Sep 10, 2026 - added a commit that references this issue
on Sep 15, 2026 - added a commit that references this issue
on Sep 20, 2026 - added a commit that references this issue
on Sep 21, 2026
Metadata
Metadata
Assignees
Labels
addonsIssues and PRs related to native addons.Issues and PRs related to native addons.c++Issues and PRs that require attention from people who are familiar with C++.Issues and PRs that require attention from people who are familiar with C++.
Version
Node.js headers 26.4.0 or newer
Node.js runtime 26.0.0 up to and including 26.3.1
Platform
Subsystem
src, addons
What steps will reproduce the bug?
The crash depends on header and runtime version. So you will need headers from e.g. Node.js 26.4.0 and two runtimes (e.g. 26.2.0 and 26.4.0)
ObjectWrapaddon.cc:
index.js:
g++ -std=c++20 -fPIC -shared \ -I</path/to/node-v26.4.0-linux-x64/include/node> \ -DNODE_GYP_MODULE_NAME=addon \ -o addon.node addon.ccHow often does it reproduce? Is there a required condition?
Deterministically with 5/5 runs.
See this table for when it crashes:
I.e. it crashes with headers >= 26.4.0 when runtime <= 26.3.1.
A explicit trigger of the gc via
global.gc()will not cause the failure, it has to be an allocation-driven one.What is the expected behavior? Why is that the expected behavior?
A pre-built addon that is built against headers of one 26.x release should keep working on another 26.x runtime
What do you see instead?
Additional information
The causing code change in 26.4.0 is the
RemoveCleanupHook();line added to destructor in commit 7ac3fe1. The call interacts with the improvement of theRemoveEnvironmentCleanupHookfunction in 1723773.When the destructor is called due to headers being 26.4.0 or newer, but the runtime being <= 26.3.1, then it can trigger the
CHECK_NOT_NULL(env);of theRemoveEnvironmentCleanupHookfunction.Refs: #63642 #63985