Automattic/mongoose · error · MongooseError

sort() options argument must be an object or nullish

Error message

sort() options argument must be an object or nullish

What it means

The second argument to sort(), when present, must be an options object or nullish; its only documented key is override, which replaces the existing sort instead of merging. A primitive in that slot — .sort({ a: 1 }, true), .sort(spec, -1) — throws this MongooseError before any sort is applied.

Source

Thrown at lib/query.js:3140

 *
 * #### Note:
 *
 * Cannot be used with `distinct()`
 *
 * @param {object|string|Array<Array<(string | number)>>} arg
 * @param {object} [options]
 * @param {boolean} [options.override=false] If true, replace existing sort options with `arg`
 * @return {Query} this
 * @see cursor.sort https://www.mongodb.com/docs/manual/reference/method/cursor.sort/
 * @api public
 */

Query.prototype.sort = function(arg, options) {
  if (arguments.length > 2) {
    throw new MongooseError('sort() takes at most 2 arguments');
  }
  if (options != null && typeof options !== 'object') {
    throw new MongooseError('sort() options argument must be an object or nullish');
  }

  if (this.options.sort == null) {
    this.options.sort = {};
  }
  if (options?.override) {
    this.options.sort = {};
  }
  const sort = this.options.sort;
  if (typeof arg === 'string') {
    const properties = arg.indexOf(' ') === -1 ? [arg] : arg.split(' ');
    for (let property of properties) {
      const ascend = '-' == property[0] ? -1 : 1;
      if (ascend === -1) {
        property = property.slice(1);
      }
      if (specialProperties.has(property)) {
        continue;

View on GitHub (pinned to 49cdab0136)

Solutions

  1. Pass { override: true } when you want the new sort to replace the accumulated one
  2. Otherwise omit the second argument or pass null

Example fix

// before
q.sort({ createdAt: -1 }, true);

// after
q.sort({ createdAt: -1 }, { override: true });
Defensive patterns

Strategy: type-guard

Validate before calling

const sortOpts = wantOverride === true ? { override: true } : undefined;
q.sort(spec, sortOpts);

Type guard

const isSortOptions = (v) => v == null || (typeof v === 'object' && !Array.isArray(v));

Prevention

When it happens

Trigger: .sort({ createdAt: -1 }, true) expecting the boolean to mean 'override'; .sort('a', 1) reusing the (field, direction) habit; passing a string flag as the second argument.

Common situations: Confusing the options slot with a direction argument; copying the (arg, options) shape but passing a feature-flag boolean; partial refactors from positional direction to options.

Related errors


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