nodejs/node · error · TypeError

invalid interceptor

Error message

invalid interceptor

What it means

TypeError thrown by Dispatcher.compose() when an interceptor returns a value that is not a function of arity 2 (opts, handler). After calling interceptor(dispatch), undici requires the result to be a non-null function whose .length === 2, since the dispatch contract is (opts, handler) => boolean. A null return, a non-function, or a function with the wrong arity all trigger this.

Source

Thrown at deps/undici/src/lib/dispatcher/dispatcher.js:34

  compose (...args) {
    // So we handle [interceptor1, interceptor2] or interceptor1, interceptor2, ...
    const interceptors = Array.isArray(args[0]) ? args[0] : args
    let dispatch = this.dispatch.bind(this)

    for (const interceptor of interceptors) {
      if (interceptor == null) {
        continue
      }

      if (typeof interceptor !== 'function') {
        throw new TypeError(`invalid interceptor, expected function received ${typeof interceptor}`)
      }

      dispatch = interceptor(dispatch)

      if (dispatch == null || typeof dispatch !== 'function' || dispatch.length !== 2) {
        throw new TypeError('invalid interceptor')
      }
    }

    return new Proxy(this, {
      get: (target, key) => key === 'dispatch' ? dispatch : target[key]
    })
  }
}

module.exports = Dispatcher

View on GitHub (pinned to 1b2de5e052)

Solutions

  1. Ensure the interceptor returns (opts, handler) => dispatch(opts, handler) shaped exactly with two declared parameters.
  2. If you pre-bind arguments, wrap so the returned function declares (opts, handler) explicitly.
  3. Always return the new dispatch function; do not rely on implicit returns from blocks.

Example fix

// before
client.compose((dispatch) => {
  return (opts) => dispatch(opts) // wrong arity, no handler
})
// after
client.compose((dispatch) => {
  return (opts, handler) => dispatch(opts, handler)
})
Defensive patterns

Strategy: validation

Validate before calling

function checkInterceptor(fn) {
  const out = fn(cur => (opts, handler) => cur(opts, handler));
  if (out == null || typeof out !== 'function' || out.length !== 2) {
    throw new TypeError('interceptor must return a 2-arg (opts, handler) function');
  }
  return out;
}

Type guard

typeof next === 'function' && next.length === 2

Prevention

When it happens

Trigger: Writing an interceptor that returns undefined, returns a 0/1/3-arg function, returns an object, or forgets to return. Fires at dispatcher.js:33-34.

Common situations: Interceptor wraps dispatch in a closure with extra bound args (changing .length); interceptor returns the raw handler instead of a dispatch function; missing `return` in a single-expression arrow that implicitly returns undefined; curry-style interceptor that captures opts early.

Related errors


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