expressjs/multer · error · Error

Unknown file strategy:

Error message

Unknown file strategy: 

What it means

Thrown by the FileAppender constructor at lib/file-appender.js:15 when its `strategy` argument is not one of the four recognized constants: 'NONE', 'VALUE', 'ARRAY', or 'OBJECT'. The appender uses the strategy to decide how to shape `req.files` (omit, single value, array, or keyed object) and to insert/remove/replace placeholders during the multipart parse, so an unknown strategy is treated as a programmer error and aborts immediately. The trailing space in 'Unknown file strategy: ' tells you `strategy` stringified to an empty value — i.e. it was `undefined` or `''`. Under normal use this is unreachable: every public method on the Multer prototype (single/array/fields/none/any in index.js) passes a hard-coded valid constant to `_makeMiddleware`, which then forwards it as `options.fileStrategy` to make-middleware.js:25 and finally to `new FileAppender(fileStrategy, req)` at make-middleware.js:143.

Solutions

  1. Use the documented public API (multer().single(), .array(), .fields(), .none(), .any()) — these always supply a valid strategy constant and cannot reach this branch.
  2. If you extend Multer, always pass one of the four constants as the second argument to `_makeMiddleware`: 'VALUE' (single file), 'ARRAY' (array/any), 'OBJECT' (fields), 'NONE' (no files).
  3. If you monkey-patch `_makeMiddleware`, preserve both arguments: `const orig = Multer.prototype._makeMiddleware; Multer.prototype._makeMiddleware = function (f, s) { /* log */ return orig.call(this, f, s); }`.
  4. If you construct FileAppender directly in a custom storage engine, pass a literal constant from the set above — never a computed/optional value.
  5. Audit your code for any `delete Multer.prototype.single` / reassignment of the prototype methods that could leave fileStrategy unset.

Example fix

// before (extends Multer but forgets the strategy -> 'Unknown file strategy: ')
Multer.prototype.uploadPair = function (name) {
  return this._makeMiddleware([{ name, maxCount: 2 }])
}

// after
Multer.prototype.uploadPair = function (name) {
  return this._makeMiddleware([{ name, maxCount: 2 }], 'ARRAY')
}
Defensive patterns

Strategy: validation

Validate before calling

const VALID_STRATEGIES = new Set(['NONE', 'VALUE', 'ARRAY', 'OBJECT']);

function assertFileStrategy(strategy) {
  if (!VALID_STRATEGIES.has(strategy)) {
    throw new Error(
      'Invalid file strategy ' + JSON.stringify(strategy) +
      '; expected one of ' + Array.from(VALID_STRATEGIES).join(', ')
    );
  }
}

// before reaching FileAppender / _makeMiddleware:
assertFileStrategy(myStrategy);

Type guard

const FILE_STRATEGIES = new Set(['NONE', 'VALUE', 'ARRAY', 'OBJECT']);

function isFileStrategy(s) {
  return typeof s === 'string' && FILE_STRATEGIES.has(s);
}

// usage when extending Multer:
// const strat = isFileStrategy(myStrat) ? myStrat : 'VALUE';

Try / catch

// This error fires per-request inside make-middleware.js. A catch is only useful
// to convert it into a clean 500 instead of an unhandled throw.
app.use((err, req, res, next) => {
  if (/Unknown file strategy/.test(err && err.message)) {
    return res.status(500).json({ error: 'Server file-handling misconfigured' });
  }
  next(err);
});

Prevention

When it happens

Trigger: Calling the internal `multerInstance._makeMiddleware(fields)` WITHOUT the second `fileStrategy` argument (signature is `_makeMiddleware(fields, fileStrategy)` at index.js:26). Subclassing or monkey-patching Multer and overriding single/array/fields/none/any but forgetting to pass a strategy constant. Replacing `Multer.prototype._makeMiddleware` with a wrapper that drops the second arg. Constructing `new FileAppender(undefined, req)` directly from a custom storage plugin or fork. The strategy is set ONLY inside the setup() closures returned by the public methods, so any path that bypasses those closures and supplies its own setup() without a `fileStrategy` key reproduces the error.

Common situations: Developers extending Multer (e.g. to add a custom field handler) who call `this._makeMiddleware(myFields)` and omit the strategy. A fork or wrapper that copies index.js but misses one of the strategy constants. A monkey-patch (e.g. for logging) that wraps `_makeMiddleware` and forwards only the first argument. Loading two different multer versions where one monkey-patches the other. Almost never seen in vanilla usage of the documented API.

Related errors


AI-assisted analysis of expressjs/multer@ece6735083 (2026-08-05). Data as JSON: /api/errors/af74b68b67037989. Report an issue: GitHub.

Appendix: source

Thrown at lib/file-appender.js:15

function arrayRemove (arr, item) {
  var idx = arr.indexOf(item)
  if (~idx) arr.splice(idx, 1)
}

function FileAppender (strategy, req) {
  this.strategy = strategy
  this.req = req

  switch (strategy) {
    case 'NONE': break
    case 'VALUE': break
    case 'ARRAY': req.files = []; break
    case 'OBJECT': req.files = Object.create(null); break
    default: throw new Error('Unknown file strategy: ' + strategy)
  }
}

FileAppender.prototype.insertPlaceholder = function (file) {
  var placeholder = {
    fieldname: file.fieldname
  }

  switch (this.strategy) {
    case 'NONE': break
    case 'VALUE': break
    case 'ARRAY': this.req.files.push(placeholder); break
    case 'OBJECT':
      if (this.req.files[file.fieldname]) {
        this.req.files[file.fieldname].push(placeholder)
      } else {
        this.req.files[file.fieldname] = [placeholder]
      }

View on GitHub (pinned to ece6735083)