{"record":{"id":"52406ea2c0ec997c","repo":"expressjs/multer","slug":"expected-object-for-argument-options","errorCode":null,"errorMessage":"Expected object for argument options","messagePattern":"Expected object for argument options","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"index.js","lineNumber":245,"sourceCode":"\n/**\n * Create a multer instance. Text fields are parsed into `req.body`; files go to\n * `req.file` or `req.files` depending on the method used.\n *\n * @param {Options} [options]\n * @returns {Multer}\n * @throws {TypeError} If `options` is not an object\n */\nfunction multer (options) {\n  if (options === undefined) {\n    return new Multer({})\n  }\n\n  if (typeof options === 'object' && options !== null) {\n    return new Multer(options)\n  }\n\n  throw new TypeError('Expected object for argument options')\n}\n\nmodule.exports = multer\nmodule.exports.diskStorage = diskStorage\nmodule.exports.memoryStorage = memoryStorage\nmodule.exports.MulterError = MulterError\n","sourceCodeStart":227,"sourceCodeEnd":252,"githubUrl":"https://github.com/expressjs/multer/blob/35979e5afbb814bdb4b750ce028b125eb84c53af/index.js#L227-L252","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before (throws TypeError: Expected object for argument options)\nconst upload = multer('uploads/')\n// or\nconst upload = multer(null)\n\n// after\nconst upload = multer({ dest: 'uploads/' })\n// or, for defaults:\nconst upload = multer()\n// or, with a storage engine:\nconst upload = multer({ storage: multer.diskStorage({ destination: 'uploads/' }) })","handlingStrategy":"type-guard","validationCode":"function normalizeMulterOptions(o) {\n  if (o === undefined) return {};\n  if (o !== null && typeof o === 'object' && !Array.isArray(o)) return o;\n  throw new TypeError('multer options must be an object, got ' + typeof o);\n}\n\n// then:\nconst upload = multer(normalizeMulterOptions(maybeBadConfig));","typeGuard":"function isMulterOptions(o) {\n  if (o === undefined) return true;\n  if (o === null || Array.isArray(o)) return false;\n  if (typeof o !== 'object') return false;\n  // optional: shape checks for known keys\n  const k = Object.keys(o);\n  const allowed = new Set(['storage', 'dest', 'limits', 'preservePath', 'defParamCharset', 'fileFilter']);\n  return k.every(key => allowed.has(key));\n}\n\n// usage:\n// const upload = isMulterOptions(opts) ? multer(opts) : multer();","tryCatchPattern":"// Boot-time guard: configuration errors should crash startup, not a request.\nlet upload;\ntry {\n  upload = multer(opts);\n} catch (err) {\n  if (err instanceof TypeError && /Expected object for argument options/.test(err.message)) {\n    console.error('Invalid multer config:', opts, err.message);\n    process.exit(1); // fail fast at boot\n  }\n  throw err;\n}","preventionTips":["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."],"tags":["configuration","api-misuse","validation","javascript","express","typescript"],"backgroundTag":null,"analyzedSha":"35979e5afbb814bdb4b750ce028b125eb84c53af","analyzedAt":"2026-08-05T14:54:55.172Z","contentChangedAt":"2026-08-05T14:54:55.172Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}