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
worker_threads Worker exit aborts (SIGABRT) when a native addon (fsevents) has an in-flight napi_threadsafe_function — napi_release_threadsafe_function / uv_mutex_lock #65100
i.e. it starts a native fsevents watch (which registers a napi_threadsafe_function under the hood) and exits the worker shortly
after, without explicitly stopping the watcher first.
How often does it reproduce? Is there a required condition?
100% reproducible on Node.js v24.15.0+ on macOS. Crashes on the very first
worker. 0% reproducible on Node.js v24.11.0/v24.11.1 (ran 50 workers cleanly).
What is the expected behavior?
All workers start, watch, and exit cleanly with code 0:
worker 0 exited with code 0
...
worker 49 exited with code 0
done, no crash across 50 workers
(This is what actually happens on v24.11.0.)
What do you see instead?
The whole process aborts with SIGABRT (exit code 134) on the very first
worker — before any of the console.log lines are even printed, since the
abort takes down the entire process (all worker threads share one OS
process).
$ node main.mjs 50
Abort trap: 6
$ echo $?
134
macOS crash reporter consistently shows the same stack trace on the
"WorkerThread":
i.e. during worker-thread Environment teardown, napi_release_threadsafe_function
attempts uv_mutex_lock while finalizing fsevents' native threadsafe
function, and this ends in abort() instead of a clean/graceful teardown.
Additional context
This was originally found as a crash inside a real-world Next.js 16.3.0
monorepo build (next build --turbopack), where Next's build worker threads
transitively load fsevents (via chokidar/watchpack) and exit shortly
after doing their work. The exact same crash signature (same stack trace)
was observed across 15+ independent crash reports collected via macOS's
crash reporter during real builds, before being reduced to this minimal,
Next.js-free, fsevents-only reproduction.
It doesn't reproduce in a fresh create-next-app project (which doesn't
happen to have an active fsevents watcher inside its build workers) —
only projects where a native addon with an in-flight napi_threadsafe_function is active in a worker thread at worker-exit
time.
Node v24.19.0 (official darwin-arm64 tarball): SIGABRT (exit code 134) on the very first worker, 3/3 runs, nothing printed to stdout before the abort — matching the report exactly.
Node v22.22.2 (same machine, same checkout, control): all 50 workers exit code 0, done, no crash across 50 workers.
One setup note for anyone else reproducing: npm install fails in node-gyp rebuild (gyp: binding.gyp not found) because fsevents 2.3.3 ships only a prebuilt fsevents.node with no gyp sources. npm install --ignore-scripts installs it fine, the addon loads (typeof require('fsevents').watch === 'function'), and the crash reproduces identically — so the abort is in N-API threadsafe-function teardown on worker exit, not a build-environment artifact.
(Disclosure: reproduction run and comment prepared with AI assistance; results are from real executions on the hardware described.)
Activity
g0rdonL commentedon Aug 9, 2026
Independent reproduction confirmed — macOS Apple Silicon (arm64), Darwin 25.5.0.
Ran the minimal repro repo (https://github.com/mastoj/node24-fsevents-worker-threads-abort) as-is, 50 workers:
Node v24.19.0 (official darwin-arm64 tarball): SIGABRT (exit code 134) on the very first worker, 3/3 runs, nothing printed to stdout before the abort — matching the report exactly.
Node v22.22.2 (same machine, same checkout, control): all 50 workers exit code 0,
done, no crash across 50 workers.One setup note for anyone else reproducing:
npm installfails innode-gyp rebuild(gyp: binding.gyp not found) because fsevents 2.3.3 ships only a prebuiltfsevents.nodewith no gyp sources.npm install --ignore-scriptsinstalls it fine, the addon loads (typeof require('fsevents').watch === 'function'), and the crash reproduces identically — so the abort is in N-API threadsafe-function teardown on worker exit, not a build-environment artifact.(Disclosure: reproduction run and comment prepared with AI assistance; results are from real executions on the hardware described.)
node-api: avoid TSFN mutex reentry during teardown
fix: use worker threads for Turbopack's PostCSS runtime