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
- Check the value you pass: console.log(typeof mw) — if undefined, fix the import (often .default) or call the factory function.
- For conditional registration, wrap in an if statement instead of passing a falsy expression: if (flag) app.use(mw).
- 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
- Many middleware packages export factories — call them: app.use(cors()) not app.use(cors).
- Check the module's export shape (default vs named export) when using ESM/CJS interop; require('x').default is a common miss.
- Verify each element when spreading arrays of middleware into app.use.
- Fail fast at startup: register all middleware synchronously so a bad value crashes on boot, not on first request.
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
- name argument is required to req.get
- name must be a string to req.get
- Invalid status code: ${JSON.stringify(code)}. Status code mu
- callback function required
- Failed to lookup view "' + name + '" in views ' + dirs
AI-assisted analysis of expressjs/express@a3714473fe (2026-07-31).
Data as JSON: /data/errors/e079cce1487169b8.json.
Report an issue: GitHub ↗.