nodejs/node · error · TypeError

invalid interceptor, expected function received ${typeof int

Error message

invalid interceptor, expected function received ${typeof interceptor}

What it means

TypeError thrown by Dispatcher.compose() when an interceptor is not null/undefined and is not a function. Interceptors must be functions of shape (dispatch) => newDispatch. Nullish interceptors are silently skipped, but any other non-function type (object, number, string) is rejected.

Source

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

    throw new Error('not implemented')
  }

  destroy () {
    throw new Error('not implemented')
  }

  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. Pass interceptor factory functions, e.g. client.compose(redirect({ maxRedirections: 10 })).
  2. Filter nullish entries before compose if your interceptor list is dynamic.
  3. Verify each import resolves to a function before adding it to the chain.

Example fix

// before
client.compose([{ maxRedirections: 10 }])
// after
const { redirect } = require('undici')
client.compose(redirect({ maxRedirections: 10 }))
Defensive patterns

Strategy: type-guard

Validate before calling

function composeSafe(client, interceptors) {
  const list = (Array.isArray(interceptors) ? interceptors : [interceptors])
    .filter(i => typeof i === 'function');
  if (list.length !== interceptors.length) {
    throw new TypeError('all interceptors must be functions');
  }
  return client.compose(list);
}

Type guard

typeof interceptor === 'function'

Prevention

When it happens

Trigger: Calling `client.compose([{}])`, `client.compose(42)`, `client.compose('redirect')`, or passing a config object where an interceptor function is expected. Fires at dispatcher.js:27-28.

Common situations: Passing an interceptor-options object instead of the interceptor factory (e.g. passing { maxRedirections: 10 } instead of redirect({ maxRedirections: 10 })); spreading an array that contains a stray non-function; importing an interceptor that defaulted to undefined and replacing it with a config object.

Related errors


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