expressjs/multer · error · TypeError
Expected object for argument options
Error message
Expected object for argument options
What it means
Thrown by the multer() factory (index.js:101) when its single `options` argument is neither `undefined` nor a non-null object. Multer uses options to pick storage, limits, fileFilter, etc., so anything that is not a plain object (or omitted entirely) cannot be normalized into a Multer instance and is rejected up front with a TypeError. The check is intentionally strict (typeof null === 'object' but null is explicitly excluded) so that downstream code in the Multer constructor can safely dereference options.storage, options.dest, options.limits, etc. It is a synchronous, configuration-time error: it fires the moment you call multer(...), before any request is handled.
Solutions
- Pass an options object literal: `multer({ dest: 'uploads/' })` instead of `multer('uploads/')`.
- If you want the defaults (memory storage, no limits), call `multer()` with no argument at all — index.js:93-95 maps undefined to `new Multer({})`.
- When passing a storage engine, wrap it: `multer({ storage: diskStorage({...}) })`, never `multer(diskStorage({...}))`.
- If `null` is meant as 'no options', normalize first: `multer(opts ?? {})` or `multer(opts || {})` before the call.
- In TypeScript, type the variable as `MutelOptions | undefined` (not `any`) so the compiler rejects non-object values at the call site.
Example fix
// before (throws TypeError: Expected object for argument options)
const upload = multer('uploads/')
// or
const upload = multer(null)
// after
const upload = multer({ dest: 'uploads/' })
// or, for defaults:
const upload = multer()
// or, with a storage engine:
const upload = multer({ storage: multer.diskStorage({ destination: 'uploads/' }) }) Defensive patterns
Strategy: type-guard
Validate before calling
function normalizeMulterOptions(o) {
if (o === undefined) return {};
if (o !== null && typeof o === 'object' && !Array.isArray(o)) return o;
throw new TypeError('multer options must be an object, got ' + typeof o);
}
// then:
const upload = multer(normalizeMulterOptions(maybeBadConfig)); Type guard
function isMulterOptions(o) {
if (o === undefined) return true;
if (o === null || Array.isArray(o)) return false;
if (typeof o !== 'object') return false;
// optional: shape checks for known keys
const k = Object.keys(o);
const allowed = new Set(['storage', 'dest', 'limits', 'preservePath', 'defParamCharset', 'fileFilter']);
return k.every(key => allowed.has(key));
}
// usage:
// const upload = isMulterOptions(opts) ? multer(opts) : multer(); Try / catch
// Boot-time guard: configuration errors should crash startup, not a request.
let upload;
try {
upload = multer(opts);
} catch (err) {
if (err instanceof TypeError && /Expected object for argument options/.test(err.message)) {
console.error('Invalid multer config:', opts, err.message);
process.exit(1); // fail fast at boot
}
throw err;
} Prevention
- Always write the multer() call with an inline object literal at the call site — never forward an untyped variable.
- In TypeScript, import Multer's options type and annotate: `const opts: Multer.Options = { dest: 'uploads/' }` so the compiler rejects non-objects.
- Treat `null` as a code smell for options — use `multer()` (no arg) for defaults instead.
- Add a unit test that calls your config builder with undefined/null/empty and asserts it returns a usable Multer instance.
- Run `standard` (the project's linter) — it will not catch this, but pairing it with `tsc --noEmit` or a runtime schema validator (zod/joi) on config will.
When it happens
Trigger: Calling `multer(null)` (typeof null === 'object' but fails the !== null guard at index.js:97), `multer('uploads/')` (passing a destination path string directly), `multer(42)`, `multer(true)`, or `multer(diskStorage(...))` (passing a storage engine directly instead of wrapping it). Passing a function, array, or any primitive as the first argument also lands on the throw at index.js:101. TypeScript callers who widen the argument to `any` and forward a runtime string/number will hit this on first require.
Common situations: Most common: a developer migrating from a library (or an old multer example) that accepted a path string and writes `multer('uploads/')` instead of `multer({ dest: 'uploads/' })`. Second: passing `null` to mean 'use defaults' (the correct call is `multer()` with no argument — index.js:93-95). Third: passing a configured storage engine straight through, e.g. `multer(diskStorage({...}))`, forgetting the `{ storage: engine }` wrapper that index.js:12 expects. Fourth: dynamic config builders that forward a possibly-null variable (`multer(opts)`) without normalizing it.
Related errors
AI-assisted analysis of expressjs/multer@35979e5afb (2026-08-05).
Data as JSON: /api/errors/52406ea2c0ec997c.
Report an issue: GitHub.
Appendix: source
Thrown at index.js:245
/**
* Create a multer instance. Text fields are parsed into `req.body`; files go to
* `req.file` or `req.files` depending on the method used.
*
* @param {Options} [options]
* @returns {Multer}
* @throws {TypeError} If `options` is not an object
*/
function multer (options) {
if (options === undefined) {
return new Multer({})
}
if (typeof options === 'object' && options !== null) {
return new Multer(options)
}
throw new TypeError('Expected object for argument options')
}
module.exports = multer
module.exports.diskStorage = diskStorage
module.exports.memoryStorage = memoryStorage
module.exports.MulterError = MulterError
View on GitHub (pinned to 35979e5afb)