Automattic/mongoose · error · Error

The skipId parameter has been removed. Use { skipId: true }

Error message

The skipId parameter has been removed. Use { skipId: true } in the options parameter instead.

What it means

Older Mongoose accepted a boolean third parameter to the Document/Model constructor to skip automatic _id generation. That positional flag moved into an options object ({ skipId: true }); passing a boolean now throws so stale call sites fail loudly rather than being misread as options.

Source

Thrown at lib/document.js:94

/**
 * The core Mongoose document constructor. You should not call this directly,
 * the Mongoose [Model constructor](./api/model.html#Model) calls this for you.
 *
 * @param {object} obj the values to set
 * @param {object} [fields] optional object containing the fields which were selected in the query returning this document and any populated paths data
 * @param {object} [options] various configuration options for the document
 * @param {boolean} [options.defaults=true] if `false`, skip applying default values to this document.
 * @param {boolean} [options.skipId=false] By default, Mongoose document if one is not provided and the document's schema does not override Mongoose's default `_id`. Set `skipId` to `true` to skip this generation step.
 * @inherits NodeJS EventEmitter https://nodejs.org/api/events.html#class-eventemitter
 * @event `init`: Emitted on a document after it has been retrieved from the db and fully hydrated by Mongoose.
 * @event `save`: Emitted when the document is successfully saved
 * @api private
 */

function Document(obj, fields, options) {
  if (typeof options === 'boolean') {
    throw new Error('The skipId parameter has been removed. Use { skipId: true } in the options parameter instead.');
  }
  options = options == null ? {} : Object.assign({}, options);
  let skipId = options.skipId;

  this.$__ = new InternalCache();

  // Support `browserDocument.js` syntax
  if (this.$__schema == null) {
    const _schema = utils.isObject(fields) && !fields.instanceOfSchema ?
      new Schema(fields) :
      fields;

    this.$__setSchema(_schema);
    fields = options;
    skipId = options.skipId;
  }

  // Avoid setting `isNew` to `true`, because it is `true` by default

View on GitHub (pinned to 49cdab0136)

Solutions

  1. Move the flag into an options object: new MyModel(obj, fields, { skipId: true })
  2. Drop the third argument entirely when default _id generation is desired

Example fix

// before
const doc = new MyModel(data, selectedFields, true);

// after
const doc = new MyModel(data, selectedFields, { skipId: true });
Defensive patterns

Strategy: validation

Validate before calling

function createDoc(Model, obj, fields, opts) {
  if (typeof opts === 'boolean') opts = { skipId: opts }; // normalize legacy positional flag
  return new Model(obj, fields, opts);
}

Prevention

When it happens

Trigger: new MyModel(obj, fields, true), new MyModel(obj, null, false), or new mongoose.Document(obj, schema, true) — any boolean as the third constructor argument.

Common situations: Codebases migrated from Mongoose 4/5/6; generic document factories that forwarded legacy positional arguments; old Stack Overflow snippets still using the boolean form.

Related errors


AI-assisted analysis of Automattic/mongoose@49cdab0136 (2026-08-21). Data as JSON: /api/errors/3e6ada5bc6b4a61b. Report an issue: GitHub.