{"record":{"id":"7b58c3a079f30472","repo":"Automattic/mongoose","slug":"arguments-must-be-aggregate-pipeline-operators","errorCode":null,"errorMessage":"Arguments must be aggregate pipeline operators","messagePattern":"Arguments must be aggregate pipeline operators","errorType":"exception","errorClass":"MongooseError","httpStatus":null,"severity":"error","filePath":"lib/aggregate.js","lineNumber":175,"sourceCode":" *\n *     aggregate.append({ $project: { field: 1 }}, { $limit: 2 });\n *\n *     // or pass an array\n *     const pipeline = [{ $match: { daw: 'Logic Audio X' }} ];\n *     aggregate.append(pipeline);\n *\n * @param {...object|object[]} ops operator(s) to append. Can either be a spread of objects or a single parameter of an object array.\n * @return {Aggregate}\n * @api public\n */\n\nAggregate.prototype.append = function() {\n  const args = (arguments.length === 1 && Array.isArray(arguments[0]))\n    ? arguments[0]\n    : [...arguments];\n\n  if (!args.every(isOperator)) {\n    throw new MongooseError('Arguments must be aggregate pipeline operators');\n  }\n\n  this._pipeline = this._pipeline.concat(args);\n\n  return this;\n};\n\n/**\n * Appends a new $addFields operator to this aggregate pipeline.\n * Requires MongoDB v3.4+ to work\n *\n * #### Example:\n *\n *     // adding new fields based on existing fields\n *     aggregate.addFields({\n *         newField: '$b.nested'\n *       , plusTen: { $add: ['$val', 10]}\n *       , sub: {","sourceCodeStart":157,"sourceCodeEnd":193,"githubUrl":"https://github.com/Automattic/mongoose/blob/49cdab01366679723b487ecb754b38570f783289/lib/aggregate.js#L157-L193","documentation":"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).","triggerScenarios":"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).","commonSituations":"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 ''.","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."],"exampleFix":"// before\nconst Model = mongoose.model(process.env.MODEL_NAME || '', schema);\n\n// after\nconst modelName = process.env.MODEL_NAME;\nif (!modelName) throw new Error('MODEL_NAME must be set to a non-empty string');\nconst Model = mongoose.model(modelName, schema);","handlingStrategy":"validation","validationCode":"function registerModel(name, schema) {\n  if (typeof name !== 'string' || name.length === 0) {\n    throw new Error(`Invalid model name: ${JSON.stringify(name)}`);\n  }\n  return mongoose.model(name, schema);\n}","typeGuard":"const isValidModelName = (name) => typeof name === 'string' && name.length > 0;","tryCatchPattern":null,"preventionTips":["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."],"tags":["mongoose","model-registration","collection-name","typeerror","validation"],"backgroundTag":"empty-model-name","analyzedSha":"49cdab01366679723b487ecb754b38570f783289","analyzedAt":"2026-08-21T22:54:00.882Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}