Automattic/mongoose · error · MongooseError

Arguments must be aggregate pipeline operators

Error message

Arguments must be aggregate pipeline operators

What it means

Mongoose throws this TypeError from utils.toCollectionName() when it tries to derive a collection name from a model name and the name is an empty string. It is called by mongoose.model(name, schema) via the global pluralizer, so registering a model with an empty name fails immediately. The empty-name check only runs when a pluralize function is configured, which is the default (mongoose-legacy-pluralize).

Source

Thrown at lib/aggregate.js:175

 *
 *     aggregate.append({ $project: { field: 1 }}, { $limit: 2 });
 *
 *     // or pass an array
 *     const pipeline = [{ $match: { daw: 'Logic Audio X' }} ];
 *     aggregate.append(pipeline);
 *
 * @param {...object|object[]} ops operator(s) to append. Can either be a spread of objects or a single parameter of an object array.
 * @return {Aggregate}
 * @api public
 */

Aggregate.prototype.append = function() {
  const args = (arguments.length === 1 && Array.isArray(arguments[0]))
    ? arguments[0]
    : [...arguments];

  if (!args.every(isOperator)) {
    throw new MongooseError('Arguments must be aggregate pipeline operators');
  }

  this._pipeline = this._pipeline.concat(args);

  return this;
};

/**
 * Appends a new $addFields operator to this aggregate pipeline.
 * Requires MongoDB v3.4+ to work
 *
 * #### Example:
 *
 *     // adding new fields based on existing fields
 *     aggregate.addFields({
 *         newField: '$b.nested'
 *       , plusTen: { $add: ['$val', 10]}
 *       , sub: {

View on GitHub (pinned to 49cdab0136)

Solutions

  1. Pass a non-empty model name: mongoose.model('User', userSchema).
  2. If the name comes from a variable, guard it before registration: if (!name) throw new Error('Model name is required').
  3. If you truly need a default collection name independent of the model, set the collection option explicitly: new Schema({}, { collection: 'users' }) and still use a valid model name.
  4. Only if you deliberately disable pluralization (mongoose.set('pluralize', null)) does the check stop running — do not use this as a workaround for an empty name.

Example fix

// before
const Model = mongoose.model(process.env.MODEL_NAME || '', schema);

// after
const modelName = process.env.MODEL_NAME;
if (!modelName) throw new Error('MODEL_NAME must be set to a non-empty string');
const Model = mongoose.model(modelName, schema);
Defensive patterns

Strategy: validation

Validate before calling

function registerModel(name, schema) {
  if (typeof name !== 'string' || name.length === 0) {
    throw new Error(`Invalid model name: ${JSON.stringify(name)}`);
  }
  return mongoose.model(name, schema);
}

Type guard

const isValidModelName = (name) => typeof name === 'string' && name.length > 0;

Prevention

When it happens

Trigger: Calling mongoose.model('', schema) or db.model('', schema); dynamically building a model name from data (e.g. mongoose.model(`${tenantId}-user`, schema)) where the variable evaluates to '' ; passing an empty string to connection.model() while a pluralizer is set (the default).

Common situations: Model names generated at runtime from environment variables, tenant/organization IDs, or config maps that are undefined or blank; refactoring that renames models and accidentally leaves an empty literal; copy-pasting a model file and deleting the name string. Also seen after upgrading when code that previously defaulted a name now yields ''.

Related errors


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