ERR_MULTIPLE_CALLBACK
Node.jsERRORNotableAsyncHIGH confidence

Callback called more than once

Production Risk

Corrupts stream state and can cause data loss or duplicated writes.

What this means

Thrown when a callback that should only be called once is invoked a second time. In stream _write(), _read(), and _transform() implementations, calling the callback (cb) more than once per invocation is always a bug and corrupts the streams internal state.

Why it happens
  1. 1Calling the _write() callback (cb) both in an if-branch and in a finally block
  2. 2Async error path that calls cb(err) and then falls through to also call cb()
  3. 3Race condition in parallel async operations that both invoke the same callback
How to reproduce

Triggered when a stream internal method callback is invoked more than once.

trigger — this will error
trigger — this will error
const { Writable } = require('stream');
const w = new Writable({
  write(chunk, enc, cb) {
    process.nextTick(cb);
    process.nextTick(cb); // second call throws ERR_MULTIPLE_CALLBACK
  }
});

expected output

Error [ERR_MULTIPLE_CALLBACK]: Callback called multiple times

Fix

Ensure the callback is called exactly once per write()

WHEN In all stream _write() and _transform() implementations

Ensure the callback is called exactly once per write()
const { Writable } = require('stream');
const w = new Writable({
  write(chunk, enc, cb) {
    doAsyncWork(chunk)
      .then(() => cb())
      .catch((err) => cb(err)); // single path
  }
});

Why this works

Promise-based handling with a single .then/.catch chain guarantees exactly one callback invocation.

Code examples
Triggerjs
const { Writable } = require('stream');
const w = new Writable({
  write(chunk, enc, cb) {
    process.nextTick(cb);
    process.nextTick(cb); // second call throws ERR_MULTIPLE_CALLBACK
  }  // this triggers ERR_MULTIPLE_CALLBACK
Handle in try/catchjs
try {
  // operation that may throw ERR_MULTIPLE_CALLBACK
  riskyOperation()
} catch (err) {
  if (err.code === 'ERR_MULTIPLE_CALLBACK') {
    console.error('ERR_MULTIPLE_CALLBACK:', err.message)
  } else {
    throw err
  }
}
Defensive pattern to avoid itjs
// Validate inputs before calling the operation
function safe_err_multiple_callback(...args) {
  // validate args here
  return performOperation(...args)
}
What not to do

Call the stream callback in both the success and finally blocks

Double-calling the callback corrupts the stream state and throws this error.

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