{"record":{"id":"1f2a3083d646250a","repo":"Automattic/mongoose","slug":"you-have-a-method-and-a-property-in-your-schema-bo","errorCode":null,"errorMessage":"You have a method and a property in your schema both named \"${method}\"","messagePattern":"You have a method and a property in your schema both named \"(.+?)\"","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/helpers/model/applyMethods.js","lineNumber":32,"sourceCode":"module.exports = function applyMethods(model, schema) {\n  const Model = require('../../model');\n\n  function apply(method, schema) {\n    Object.defineProperty(model.prototype, method, {\n      get: function() {\n        const h = {};\n        for (const k in schema.methods[method]) {\n          h[k] = schema.methods[method][k].bind(this);\n        }\n        return h;\n      },\n      configurable: true\n    });\n  }\n  for (const method of Object.keys(schema.methods)) {\n    const fn = schema.methods[method];\n    if (Object.hasOwn(schema.tree, method)) {\n      throw new Error('You have a method and a property in your schema both ' +\n        'named \"' + method + '\"');\n    }\n\n    // Avoid making custom methods if user sets a method to itself, e.g.\n    // `schema.method(save, Document.prototype.save)`. Can happen when\n    // calling `loadClass()` with a class that `extends Document`. See gh-12254\n    if (typeof fn === 'function' &&\n        Model.prototype[method] === fn) {\n      delete schema.methods[method];\n      continue;\n    }\n\n    if (schema.reserved[method] &&\n        !get(schema, `methodOptions.${method}.suppressWarning`, false)) {\n      utils.warn(`mongoose: the method name \"${method}\" is used by mongoose ` +\n        'internally, overwriting it may cause bugs. If you\\'re sure you know ' +\n        'what you\\'re doing, you can suppress this error by using ' +\n        `\\`schema.method('${method}', fn, { suppressWarning: true })\\`.`);","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/Automattic/mongoose/blob/49cdab01366679723b487ecb754b38570f783289/lib/helpers/model/applyMethods.js#L14-L50","documentation":"applyMethods copies schema.methods onto the model prototype at compile time. If a schema path (field) already exists in schema.tree with the same name, defining both a method and a property with one name would make one shadow the other on every document, so Mongoose throws Error('You have a method and a property in your schema both named ...') when Object.hasOwn(schema.tree, method) is true.","triggerScenarios":"const s = new Schema({ name: String }); s.methods.name = function () {...}; - any schema.methods key equal to an existing path name; class-based schemas via loadClass whose method or getter names collide with schema paths.","commonSituations":"Adding convenience accessors named exactly after the field (e.g. a method named password on a schema with a password path); ES class models (loadClass) with members clashing with schema fields; copy-pasting method sets between schemas.","solutions":["Rename the method (e.g. displayName() instead of name()) or rename the field.","If you wanted a computed value, use a virtual: schema.virtual('upperName').get(function () {...}) - virtuals are the right tool for derived properties.","With loadClass classes, rename class members that clash with schema paths."],"exampleFix":"// before\nconst userSchema = new Schema({ name: String });\nuserSchema.methods.name = function () { return this.name.toUpperCase(); }; // collides with path 'name'\n\n// after: differently-named method, or a virtual\nuserSchema.methods.displayName = function () { return this.name.toUpperCase(); };\n// or\nuserSchema.virtual('upperName').get(function () { return this.name.toUpperCase(); });","handlingStrategy":"validation","validationCode":"// detect method/path collisions before model compilation\nfunction assertNoMethodPathCollisions(schema) {\n  for (const method of Object.keys(schema.methods)) {\n    if (Object.hasOwn(schema.tree, method)) {\n      throw new Error(`method '${method}' collides with schema path of the same name`);\n    }\n  }\n}\nassertNoMethodPathCollisions(userSchema);\nconst User = mongoose.model('User', userSchema);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Prefix or verb-ify method names (get*, calc*, is*) so they cannot equal field names.","Prefer virtuals for derived values; reserve methods for behavior.","When using loadClass with ES classes, review class member names against schema paths."],"tags":["mongoose","schema","methods","name-collision","model-compile"],"backgroundTag":"schema-name-collision","analyzedSha":"49cdab01366679723b487ecb754b38570f783289","analyzedAt":"2026-08-21T22:54:00.882Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}