{"record":{"id":"520be7ffb5d8f9f4","repo":"Automattic/mongoose","slug":"sort-takes-at-most-2-arguments","errorCode":null,"errorMessage":"sort() takes at most 2 arguments","messagePattern":"sort\\(\\) takes at most 2 arguments","errorType":"exception","errorClass":"MongooseError","httpStatus":null,"severity":"error","filePath":"lib/query.js","lineNumber":3137,"sourceCode":" *\n *     // also possible is to use a array with array key-value pairs\n *     query.sort([['field', 'asc']]);\n *\n * #### Note:\n *\n * Cannot be used with `distinct()`\n *\n * @param {object|string|Array<Array<(string | number)>>} arg\n * @param {object} [options]\n * @param {boolean} [options.override=false] If true, replace existing sort options with `arg`\n * @return {Query} this\n * @see cursor.sort https://www.mongodb.com/docs/manual/reference/method/cursor.sort/\n * @api public\n */\n\nQuery.prototype.sort = function(arg, options) {\n  if (arguments.length > 2) {\n    throw new MongooseError('sort() takes at most 2 arguments');\n  }\n  if (options != null && typeof options !== 'object') {\n    throw new MongooseError('sort() options argument must be an object or nullish');\n  }\n\n  if (this.options.sort == null) {\n    this.options.sort = {};\n  }\n  if (options?.override) {\n    this.options.sort = {};\n  }\n  const sort = this.options.sort;\n  if (typeof arg === 'string') {\n    const properties = arg.indexOf(' ') === -1 ? [arg] : arg.split(' ');\n    for (let property of properties) {\n      const ascend = '-' == property[0] ? -1 : 1;\n      if (ascend === -1) {\n        property = property.slice(1);","sourceCodeStart":3119,"sourceCodeEnd":3155,"githubUrl":"https://github.com/Automattic/mongoose/blob/49cdab01366679723b487ecb754b38570f783289/lib/query.js#L3119-L3155","documentation":"Query.prototype.sort() accepts exactly one sort specification plus one optional options object ({ override: true }); more than two arguments throws immediately. The guard primarily catches SQL-ORM-style (field, direction) calls such as .sort('createdAt', -1), which Mongoose does not support — direction must be encoded inside the spec, not passed as a second argument.","triggerScenarios":".sort('createdAt', -1); .sort('name', 'desc'); passing a direction string or number as a second argument; three-argument calls like .sort(spec, {}, true).","commonSituations":"Developers coming from TypeORM/Sequelize/Knex where orderBy takes (field, direction); adapting MongoDB shell examples incorrectly; adding a second 'descending' argument by intuition.","solutions":["Combine into one spec: .sort({ createdAt: -1 }) or the string form .sort('-createdAt')","For multiple fields: .sort({ a: 1, b: -1 }) or .sort('a -b')","The only valid second argument is an options object, e.g. .sort(spec, { override: true }) to replace an existing sort"],"exampleFix":"// before\nconst q = Model.find().sort('createdAt', -1);\n\n// after\nconst q = Model.find().sort({ createdAt: -1 });\n// or\nconst q = Model.find().sort('-createdAt');","handlingStrategy":"validation","validationCode":"// Normalize (field, direction) input into a valid Mongoose sort spec\nfunction toSort(field, dir) {\n  if (dir == null) return { [field]: 1 };\n  const d = String(dir).trim().toLowerCase();\n  return { [field]: d.startsWith('d') || d === '-1' ? -1 : 1 };\n}\nconst q = Model.find().sort(toSort('createdAt', req.query.order));","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Remember sort() takes one spec argument plus at most an options object","Prefer object specs ({ field: -1 }) for dynamic sorting","Add unit tests around any dynamic sort builder"],"tags":["mongoose","query","sort","invalid-argument","arity"],"backgroundTag":"invalid-sort-argument","analyzedSha":"49cdab01366679723b487ecb754b38570f783289","analyzedAt":"2026-08-21T22:54:00.882Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}