nodejs/node · error · InvalidArgumentError

UND_ERR_INVALID_ARG

UND_ERR_INVALID_ARG

Error message

invalid callback

What it means

Thrown by DispatcherBase.close() when the supplied callback is neither undefined nor a function. Passing undefined makes close() return a Promise; passing a function uses the node-style (err, data) callback. Any other type is rejected synchronously with UND_ERR_INVALID_ARG.

Source

Thrown at deps/undici/src/lib/dispatcher/dispatcher-base.js:66

    return this[kDestroyed]
  }

  /** @returns {boolean} */
  get closed () {
    return this[kClosed]
  }

  close (callback) {
    if (callback === undefined) {
      return new Promise((resolve, reject) => {
        this.close((err, data) => {
          return err ? reject(err) : resolve(data)
        })
      })
    }

    if (typeof callback !== 'function') {
      throw new InvalidArgumentError('invalid callback')
    }

    if (this[kDestroyed]) {
      const err = new ClientDestroyedError()
      queueMicrotask(() => callback(err, null))
      return
    }

    if (this[kClosed]) {
      if (this[kOnClosed]) {
        this[kOnClosed].push(callback)
      } else {
        queueMicrotask(() => callback(null, null))
      }
      return
    }

    this[kClosed] = true

View on GitHub (pinned to 1b2de5e052)

Solutions

  1. Call close() with no argument to get a Promise: await client.close().
  2. Pass a node-style callback: client.close((err, data) => { ... }).
  3. Check the call site for a misplaced argument.

Example fix

// before
client.close('finished')
// after
await client.close()
Defensive patterns

Strategy: type-guard

Validate before calling

function closeSafely(client, cb) {
  if (cb !== undefined && typeof cb !== 'function') {
    throw new TypeError('close callback must be a function or undefined');
  }
  return cb === undefined ? client.close() : client.close(cb);
}

Type guard

callback === undefined || typeof callback === 'function'

Try / catch

try { client.close(maybeCb); } catch (e) { if (e.code === 'UND_ERR_INVALID_ARG') { await client.close(); } else throw e; }

Prevention

When it happens

Trigger: Calling `client.close('done')`, `client.close(null)`, `client.close({})`, or `client.close(42)`. Triggered at dispatcher-base.js:65-66.

Common situations: Passing a Promise resolve/reject handle incorrectly; passing a string event name by mistake; passing an options object where a callback was expected; refactor that dropped the callback parameter.

Related errors


AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13). Data as JSON: /api/errors/4d13801e59a92da3. Report an issue: GitHub.