{"record":{"id":"459fe6460b4b047a","repo":"Automattic/mongoose","slug":"invalid-sort-argument-must-be-a-string-or-objec","errorCode":null,"errorMessage":"Invalid sort() argument. Must be a string or object.","messagePattern":"Invalid sort\\(\\) argument\\. Must be a string or object\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"warning","filePath":"lib/aggregate.js","lineNumber":677,"sourceCode":"      if (arg[field] instanceof Object && arg[field].$meta) {\n        sort[field] = arg[field];\n        return;\n      }\n      sort[field] = desc.indexOf(arg[field]) === -1 ? 1 : -1;\n    });\n  } else if (arguments.length === 1 && typeof arg === 'string') {\n    arg.split(/\\s+/).forEach(function(field) {\n      if (!field) {\n        return;\n      }\n      const ascend = field[0] === '-' ? -1 : 1;\n      if (ascend === -1) {\n        field = field.substring(1);\n      }\n      sort[field] = ascend;\n    });\n  } else {\n    throw new TypeError('Invalid sort() argument. Must be a string or object.');\n  }\n\n  return this.append({ $sort: sort });\n};\n\n/**\n * Appends new $unionWith operator to this aggregate pipeline.\n *\n * #### Example:\n *\n *     aggregate.unionWith({ coll: 'users', pipeline: [ { $match: { _id: 1 } } ] });\n *\n * @see $unionWith https://www.mongodb.com/docs/manual/reference/operator/aggregation/unionWith\n * @param {object} options to $unionWith query as described in the above link\n * @return {Aggregate}\n * @api public\n */\n","sourceCodeStart":659,"sourceCodeEnd":695,"githubUrl":"https://github.com/Automattic/mongoose/blob/49cdab01366679723b487ecb754b38570f783289/lib/aggregate.js#L659-L695","documentation":"While building indexes for a model (Model.init() / ensureIndexes during compile or model.syncIndexes()), Mongoose inspects each index spec; MongoDB always creates a unique index on _id and does not allow a second, different index on the same key. isDefaultIdIndex() detects specs that try to redefine the _id index (e.g. { _id: 1 } or {_id: 1} with extra options), and Mongoose warns that the custom definition will not be applied as expected.","triggerScenarios":"schema.index({ _id: 1 }) or schema.index({ _id: 1 }, { unique: true, name: 'custom' }); defining { _id: { type: Schema.Types.ObjectId, index: true } } in the schema; setting sparse/expireAfterSeconds options on an _id index spec.","commonSituations":"Auto-generated index definitions from tooling that indexes every field; teams copying an index list from mongo shell explain output back into the schema; migration scripts that materialize existing DB indexes as schema.index() calls including the implicit _id one.","solutions":["Remove the _id entry from schema.index() calls — MongoDB guarantees the _id unique index automatically.","Remove index: true from the _id field definition: { _id: Schema.Types.ObjectId } is enough.","If you need a custom _id type (e.g. Number), that is supported — just do not also declare an index on it.","Run model.syncIndexes() after cleaning up and confirm via db.collection.getIndexes() that only one _id index exists."],"exampleFix":"// before\nconst schema = new Schema({ _id: { type: ObjectId, index: true } });\nschema.index({ _id: 1 }, { name: 'custom_id' });\n\n// after\nconst schema = new Schema({ _id: ObjectId }); // default unique index is automatic","handlingStrategy":"validation","validationCode":"function sanitizeIndexes(schema) {\n  const json = schema.indexes(); // [[fields, options], ...]\n  for (const [fields] of json) {\n    const keys = Object.keys(fields);\n    if (keys.length === 1 && keys[0] === '_id') {\n      throw new Error('Remove custom index on _id; MongoDB creates it automatically');\n    }\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never declare indexes on _id in schemas or schema.index().","Do not blindly convert db.collection.getIndexes() output into schema.index() calls — skip _id.","Review generated/seed schemas for index: true on _id fields."],"tags":["mongoose","indexes","mongodb","schema","warning"],"backgroundTag":"duplicate-index-definition","analyzedSha":"49cdab01366679723b487ecb754b38570f783289","analyzedAt":"2026-08-21T22:54:00.882Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}