{"record":{"id":"821fed06268824ce","repo":"Automattic/mongoose","slug":"cannot-overwrite-name-model-once-compiled-821fed","errorCode":null,"errorMessage":"Cannot overwrite `${name}` model once compiled.","messagePattern":"Cannot overwrite `(.+?)` model once compiled\\.","errorType":"exception","errorClass":"OverwriteModelError","httpStatus":null,"severity":"error","filePath":"lib/model.js","lineNumber":1026,"sourceCode":"\n  options = options || {};\n  const value = utils.isPOJO(options) ? options.value : options;\n  const clone = typeof options.clone === 'boolean' ? options.clone : true;\n  const mergePlugins = typeof options.mergePlugins === 'boolean' ? options.mergePlugins : true;\n  const overwriteModels = typeof options.overwriteModels === 'boolean' ? options.overwriteModels : false;\n\n  _checkContext(this, 'discriminator');\n\n  if (utils.isObject(schema) && !schema.instanceOfSchema) {\n    schema = new Schema(schema);\n  }\n  if (schema instanceof Schema && clone) {\n    schema = schema.clone();\n  }\n\n  schema = discriminator(this, name, schema, value, mergePlugins, options.mergeHooks, overwriteModels);\n  if (this.db.models[name] && !schema.options.overwriteModels && !overwriteModels) {\n    throw new OverwriteModelError(name);\n  }\n\n  schema.$isRootDiscriminator = true;\n  schema.$globalPluginsApplied = true;\n\n  model = this.db.model(model || name, schema, this.$__collection.name);\n  this.discriminators[name] = model;\n  const d = this.discriminators[name];\n  Object.setPrototypeOf(d.prototype, this.prototype);\n  Object.defineProperty(d, 'baseModelName', {\n    value: this.modelName,\n    configurable: true,\n    writable: false\n  });\n\n  // apply methods and statics\n  applyMethods(d, schema);\n  applyStatics(d, schema);","sourceCodeStart":1008,"sourceCodeEnd":1044,"githubUrl":"https://github.com/Automattic/mongoose/blob/49cdab01366679723b487ecb754b38570f783289/lib/model.js#L1008-L1044","documentation":"Thrown by Model.discriminator() (via OverwriteModelError) when a discriminator name is already registered on the same connection (this.db.models[name] exists). Mongoose refuses to silently replace a compiled model because existing documents, queries, and hooks hold references to the old constructor. The guard is bypassed only when the schema option `overwriteModels` is true or the `overwriteModels` argument is passed as true.","triggerScenarios":"Calling `Event.discriminator('ClickedLink', clickedSchema)` twice with the same name on one connection; a discriminator name that collides with an already-registered base or sibling model; re-executing a model-definition module against a live connection (Next.js/NestJS HMR, Jest watch) so `mongoose.model()` runs again.","commonSituations":"Hot-reloading dev servers that re-import model files; test suites that recompile models on every run without resetting mongoose; monorepos where the same model module is loaded twice through different resolve paths; serverless environments that re-use a cached connection across warm invocations.","solutions":["Reuse the existing model instead of re-registering: `const Clicked = Event.discriminators['ClickedLink'] ?? Event.discriminator('ClickedLink', clickedSchema)`","Delete the stale registration first: `mongoose.connection.deleteModel('ClickedLink')` before recompiling","Pass the overwrite flag: `Event.discriminator('ClickedLink', clickedSchema, { value: ..., mergeHooks: ... }, true)` or set `overwriteModels: true` in the schema options","Centralize all model definitions in one module that runs once per process, and export the compiled models from there"],"exampleFix":"// before (runs on every hot reload)\nEvent.discriminator('ClickedLink', clickedSchema); // OverwriteModelError on 2nd run\n\n// after\nconst ClickedLink =\n  Event.discriminators['ClickedLink'] ||\n  Event.discriminator('ClickedLink', clickedSchema);","handlingStrategy":"validation","validationCode":"// Before registering, check every registry the discriminator would land in\nconst getDiscriminator = (Model, name, schema) =>\n  Model.discriminators?.[name] ||\n  mongoose.models[name] ||\n  mongoose.connection.models[name] ||\n  Model.discriminator(name, schema);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Define every model/discriminator in exactly one module and import the compiled model elsewhere — never re-run registration","In dev with HMR (Next.js/NestJS), add a cleanup hook: `mongoose.connection.deleteModel(name)` or use the global mongoose cache pattern","When overriding is intentional, pass the `overwriteModels` argument or schema option explicitly so the intent is visible in review"],"tags":["mongoose","discriminator","model-registry","duplicate-model","hot-reload"],"backgroundTag":"duplicate-model-registration","analyzedSha":"49cdab01366679723b487ecb754b38570f783289","analyzedAt":"2026-08-21T22:54:00.882Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}