expressjs/express · error · TypeError

app.use() requires a middleware function

Error message

app.use() requires a middleware function

What it means

app.use() flattens all arguments after the optional path (lib/application.js:210) and throws at line 212-213 if no middleware functions remain. Express requires at least one function per .use() call; registering nothing is treated as a bug at wiring time rather than being silently ignored.

Source

Thrown at lib/application.js:213

  // disambiguate app.use([fn])
  if (typeof fn !== 'function') {
    var arg = fn;

    while (Array.isArray(arg) && arg.length !== 0) {
      arg = arg[0];
    }

    // first arg is the path
    if (typeof arg !== 'function') {
      offset = 1;
      path = fn;
    }
  }

  var fns = flatten.call(slice.call(arguments, offset), Infinity);

  if (fns.length === 0) {
    throw new TypeError('app.use() requires a middleware function')
  }

  // get router
  var router = this.router;

  fns.forEach(function (fn) {
    // non-express app
    if (!fn || !fn.handle || !fn.set) {
      return router.use(path, fn);
    }

    debug('.use app under %s', path);
    fn.mountpath = path;
    fn.parent = this;

    // restore .app property on req and res
    router.use(path, function mounted_app(req, res, next) {
      var orig = req.app;

View on GitHub ↗ (pinned to a3714473fe)

Solutions

  1. Check the value you pass: console.log(typeof mw) — if undefined, fix the import (often .default) or call the factory function.
  2. For conditional registration, wrap in an if statement instead of passing a falsy expression: if (flag) app.use(mw).
  3. Ensure arrays passed to app.use() actually contain functions and aren't empty.

Example fix

// before
const logger = require('my-logger').logger; // undefined
app.use(logger);
// after
const { createLogger } = require('my-logger');
app.use(createLogger());
Defensive patterns

Strategy: type-guard

Validate before calling

if (typeof middleware !== 'function') {
  throw new TypeError(`app.use() expected a function, got ${typeof middleware}`);
}
app.use(middleware);

Type guard

function isMiddleware(fn) {
  return typeof fn === 'function';
}

Try / catch

try {
  app.use(require('./middleware/logger'));
} catch (err) {
  if (/requires a middleware function/.test(err.message)) {
    // most often: module exported a factory or an object — check whether you need to CALL it, e.g. logger()
  }
  throw err;
}

Prevention

When it happens

Trigger: app.use('/api') with no function; app.use(undefined) or app.use('/x', undefined); app.use([]) or an array that flattens to empty; passing the result of a factory/require() that returned undefined instead of a middleware function.

Common situations: A middleware module whose export changed shape (e.g. forgetting to call the factory: app.use(cors) vs app.use(cors())) combined with a missing/undefined import; ESM/CJS interop where require(pkg).default was needed; conditional middleware like app.use(flag && mw) where flag is false; a typo'd import name yielding undefined. Frequently surfaces after upgrading a middleware package that moved to a default export.

Related errors


AI-assisted analysis of expressjs/express@a3714473fe (2026-07-31). Data as JSON: /data/errors/e079cce1487169b8.json. Report an issue: GitHub ↗.