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
- Pass a non-empty model name: mongoose.model('User', userSchema).
- If the name comes from a variable, guard it before registration: if (!name) throw new Error('Model name is required').
- 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.
- 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
- Never build model names by string interpolation of env vars or tenant IDs without an empty check.
- Centralize model registration in one factory so the name check lives in a single place.
- Fail fast at startup config validation rather than at first model compile.
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
- A setter must be a function.
- A getter must be a function.
- Collection name must be a string
- Invalid addFields() argument. Must be an object
- Invalid project() argument. Must be string or object
AI-assisted analysis of Automattic/mongoose@49cdab0136 (2026-08-21).
Data as JSON: /api/errors/7b58c3a079f30472.
Report an issue: GitHub.