ERR_NAPI_TSFN_STOP_IDLE_LOOP
Node.jsERRORCriticalNativeHIGH confidence

Failed to stop the libuv idle loop for thread-safe function

Production Risk

Low — only affects native addons; follow Node-API documentation strictly.

What this means

Thrown when the Node-API attempts to stop the libuv idle handler used to keep the event loop alive for a thread-safe function, but the stop operation fails. This is an internal error in the native addon layer and usually indicates a libuv state problem.

Why it happens
  1. 1Thread-safe function lifecycle mismanagement in a native addon
  2. 2Calling napi_release_threadsafe_function() from the wrong thread or in the wrong state
How to reproduce

Triggered from native C++ addons when the thread-safe function cleanup fails.

trigger — this will error
trigger — this will error
// This error originates in native addon C++ code
// It cannot be directly triggered from JavaScript
// Occurs when napi_release_threadsafe_function() fails internally

expected output

Error [ERR_NAPI_TSFN_STOP_IDLE_LOOP]: Failed to stop the idle loop for a threadsafe function

Fix

Follow Node-API thread-safe function lifecycle correctly in native code

WHEN When implementing thread-safe functions in native addons

Follow Node-API thread-safe function lifecycle correctly in native code
// In native C++ code:
// 1. Create with napi_create_threadsafe_function()
// 2. Acquire before use: napi_acquire_threadsafe_function()
// 3. Release after use: napi_release_threadsafe_function()
// 4. The finalizer fires on the main thread when all refs are released

Why this works

Proper lifecycle management ensures the libuv idle handler is stopped cleanly without errors.

Code examples
Triggerjs
// This error originates in native addon C++ code
// It cannot be directly triggered from JavaScript
// Occurs when napi_release_threadsafe_function() fails internally  // this triggers ERR_NAPI_TSFN_STOP_IDLE_LOOP
Handle in try/catchjs
try {
  // operation that may throw ERR_NAPI_TSFN_STOP_IDLE_LOOP
  riskyOperation()
} catch (err) {
  if (err.code === 'ERR_NAPI_TSFN_STOP_IDLE_LOOP') {
    console.error('ERR_NAPI_TSFN_STOP_IDLE_LOOP:', err.message)
  } else {
    throw err
  }
}
Defensive pattern to avoid itjs
// Validate inputs before calling the operation
function safe_err_napi_tsfn_stop_idle_loop(...args) {
  // validate args here
  return performOperation(...args)
}
What not to do

Release a thread-safe function from a non-main thread without proper acquire/release pairing

Unpaired acquire/release calls corrupt the libuv state.

Sources
Official documentation ↗

Node.js Error Codes Documentation

Content generated with AI assistance and reviewed for accuracy. Found an error? hello@errcodes.dev

← All Node.js errors