Automattic/mongoose · warning · MongooseError

Aggregate `near()` must be called with non-nullish argument

Error message

Aggregate `near()` must be called with non-nullish argument

What it means

When a schema path is added, Mongoose checks whether the FIRST segment of the dotted path collides with a reserved name on the Document prototype (save, errors, schema, on, once, emit, get, set, init, isNew, toObject, toJSON, ...). Because these become properties/methods on every document, a user path with the same name shadows them and can break Mongoose internals. Since Mongoose 5 this is only a warning (utils.warn), not an exception; special properties like $.foo still throw, but reserved names just warn unless suppressed.

Source

Thrown at lib/aggregate.js:410

 *       maxDistance: 0.008,
 *       query: { type: "public" },
 *       includeLocs: "dist.location",
 *       spherical: true,
 *     });
 *
 * @see $geoNear https://www.mongodb.com/docs/manual/reference/aggregation/geoNear/
 * @method near
 * @memberOf Aggregate
 * @instance
 * @param {object} arg
 * @param {object|number[]} arg.near GeoJSON point or coordinates array
 * @return {Aggregate}
 * @api public
 */

Aggregate.prototype.near = function(arg) {
  if (arg == null) {
    throw new MongooseError('Aggregate `near()` must be called with non-nullish argument');
  }
  if (arg.near == null) {
    throw new MongooseError('Aggregate `near()` argument must have a `near` property');
  }
  const coordinates = Array.isArray(arg.near) ? arg.near : arg.near.coordinates;
  if (typeof arg.near === 'object' && (!Array.isArray(coordinates) || coordinates.length < 2 || coordinates.find(c => typeof c !== 'number'))) {
    throw new MongooseError(`Aggregate \`near()\` argument has invalid coordinates, got "${coordinates}"`);
  }

  const op = {};
  op.$geoNear = arg;
  return this.append(op);
};

/*!
 * define methods
 */

View on GitHub (pinned to 49cdab0136)

Solutions

  1. Rename the path to something non-reserved, e.g. 'save' -> 'isSaved', 'on' -> 'activeAt', 'errors' -> 'validationIssues' (you can keep the MongoDB key different using the 'alias' option or a virtual).
  2. If the collision is intentional and tested, silence it per schema: new Schema({...}, { suppressReservedKeysWarning: true }).
  3. Use field aliases to keep the stored key: { errors: { type: String, alias: 'docErrors' } } and access doc.docErrors.
  4. Audit usages of doc.toObject()/JSON serialization after renaming to make sure API consumers are updated.

Example fix

// before
const schema = new Schema({ on: Date, errors: [String] }); // warns

// after
const schema = new Schema({
  activeAt: { type: Date, alias: 'on' },
  issues: { type: [String], alias: 'errors' }
});
Defensive patterns

Strategy: validation

Validate before calling

const RESERVED = new Set(['save','errors','schema','on','once','emit','init','get','set','isNew','toObject','toJSON','populate','remove','deleteOne','updateOne','overwrite','collection','db','model','$__']);
function assertSafePaths(definition) {
  for (const key of Object.keys(definition)) {
    if (RESERVED.has(key.split('.')[0])) {
      throw new Error(`Field "${key}" collides with a reserved Document name; rename it or use suppressReservedKeysWarning`);
    }
  }
}

Prevention

When it happens

Trigger: Defining new Schema({ errors: String }), { save: Boolean }, { on: Date }, { schema: Mixed }, or a nested first segment like 'init.name' in the schema definition; also indirect definitions via schema.add({ ... }) or a nested path whose first piece is reserved.

Common situations: Logging/event schemas that naturally want a field named 'on' or 'init'; audit schemas with an 'errors' array; migrating a MongoDB collection whose documents contain keys that collide with Document methods; ORM-agnostic code reused across libraries where the same field name is fine elsewhere.

Related errors


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