[node.js] Cannot overwrite model once compiled Mongoose

Not Sure what I'm doing wrong, here is my check.js

var db = mongoose.createConnection('localhost', 'event-db');
db.on('error', console.error.bind(console, 'connection error:'));

var a1= db.once('open',function(){
var user = mongoose.model('users',{ 
       name:String,
       email:String,
       password:String,
       phone:Number,
      _enabled:Boolean
     });

user.find({},{},function (err, users) {
    mongoose.connection.close();
    console.log("Username supplied"+username);
    //doSomethingHere })
    });

and here is my insert.js

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/event-db')

var user = mongoose.model('users',{
     name:String,
     email:String,
     password: String,
     phone:Number,
     _enabled:Boolean
   });

var new_user = new user({
     name:req.body.name,
     email: req.body.email,
     password: req.body.password,
     phone: req.body.phone,
     _enabled:false
   });

new_user.save(function(err){
    if(err) console.log(err); 
   });

Whenever I'm trying to run check.js, I'm getting this error

Cannot overwrite 'users' model once compiled.

I understand that this error comes due to mismatching of Schema, but I cannot see where this is happening ? I'm pretty new to mongoose and nodeJS.

Here is what I'm getting from the client interface of my MongoDB:

MongoDB shell version: 2.4.6 connecting to: test 
> use event-db 
  switched to db event-db 
> db.users.find() 
  { "_id" : ObjectId("52457d8718f83293205aaa95"), 
    "name" : "MyName", 
    "email" : "[email protected]", 
    "password" : "myPassword", 
    "phone" : 900001123, 
    "_enable" : true 
  } 
>

This question is related to node.js mongodb model express mongoose

The answer is


I have been experiencing this issue & it was not because of the schema definitions but rather of serverless offline mode - I just managed to resolve it with this:

serverless offline --skipCacheInvalidation

Which is mentioned here https://github.com/dherault/serverless-offline/issues/258

Hopefully that helps someone else who is building their project on serverless and running offline mode.


I had this issue while unit testing.

The first time you call the model creation function, mongoose stores the model under the key you provide (e.g. 'users'). If you call the model creation function with the same key more than once, mongoose won't let you overwrite the existing model.

You can check if the model already exists in mongoose with:

let users = mongoose.model('users')

This will throw an error if the model does not exist, so you can wrap it in a try/catch in order to either get the model, or create it:

let users
try {
  users = mongoose.model('users')
} catch (error) {
  users = mongoose.model('users', <UsersSchema...>)
}

Here is one more reason why this can happen. Perhaps this can help someone else. Notice the difference, Members vs Member. They must be the same...

export default mongoose.models.Members || mongoose.model('Member', FamilySchema)

Change to:

export default mongoose.models.Member || mongoose.model('Member', FamilySchema)

is because your schema is already, validate before create new schema.

var mongoose = require('mongoose');
module.exports = function () {
var db = require("../libs/db-connection")();
//schema de mongoose
var Schema = require("mongoose").Schema;

var Task = Schema({
    field1: String,
    field2: String,
    field3: Number,
    field4: Boolean,
    field5: Date
})

if(mongoose.models && mongoose.models.tasks) return mongoose.models.tasks;

return mongoose.model('tasks', Task);

I have a situation where I have to create the model dynamically with each request and because of that I received this error, however, what I used to fix it is using deleteModel method like the following:

var contentType = 'Product'

var contentSchema = new mongoose.Schema(schema, virtuals);

var model = mongoose.model(contentType, contentSchema);

mongoose.deleteModel(contentType);

I hope this could help anybody.


If you want to overwrite the existing class for different collection using typescript
then you have to inherit the existing class from different class.

export class User extends Typegoose{
  @prop
  username?:string
  password?:string
}


export class newUser extends User{
    constructor() {
        super();
    }
}

export const UserModel = new User ().getModelForClass(User , { schemaOptions: { collection: "collection1" } });

export const newUserModel = new newUser ().getModelForClass(newUser , { schemaOptions: { collection: "collection2" } });

What you can also do is at your export, make sure to export an existing instance if one exists.

Typescript solution:

import { Schema, Document, model, models } from 'mongoose';

const UserSchema: Schema = new Schema({
    name: {
        type: String
    }
});

export interface IUser extends Document {
    name: string
}

export default models.Users || model<IUser>('Users', UserSchema);

I solved this issue by doing this

// Created Schema - Users
// models/Users.js
const mongoose = require("mongoose");

const Schema = mongoose.Schema;

export const userSchema = new Schema({
  // ...
});

Then in other files

// Another file
// index.js
import { userSchema } from "../models/Users";
const conn = mongoose.createConnection(process.env.CONNECTION_STRING, {
    useNewUrlParser: true,
    useUnifiedTopology: true,
});
conn.models = {};
const Users = conn.model("Users", userSchema);
const results = await Users.find({});

Better Solution

let User;
try {
  User = mongoose.model("User");
} catch {
  User = mongoose.model("User", userSchema);
}

I hope this helps...


If you are working with expressjs, you may need to move your model definition outside app.get() so it's only called once when the script is instantiated.


I know there is an accepted solution but I feel that the current solution results in a lot of boilerplate just so that you can test Models. My solution is essentially to take you model and place it inside of a function resulting in returning the new Model if the Model has not been registered but returning the existing Model if it has.

function getDemo () {
  // Create your Schema
  const DemoSchema = new mongoose.Schema({
    name: String,
    email: String
  }, {
    collection: 'demo'
  })
  // Check to see if the model has been registered with mongoose
  // if it exists return that model
  if (mongoose.models && mongoose.models.Demo) return mongoose.models.Demo
  // if no current model exists register and return new model
  return mongoose.model('Demo', DemoSchema)
}

export const Demo = getDemo()

Opening and closing connections all over the place is frustrating and does not compress well.

This way if I were to require the model two different places or more specifically in my tests I would not get errors and all the correct information is being returned.


just export like this exports.User = mongoose.models.User || mongoose.model('User', userSchema);


I had this issue while 'watching' tests. When the tests were edited, the watch re-ran the tests, but they failed due to this very reason.

I fixed it by checking if the model exists then use it, else create it.

import mongoose from 'mongoose';
import user from './schemas/user';

export const User = mongoose.models.User || mongoose.model('User', user);

For all people ending here because of a codebase with a mix of Typegoose and Mongoose :

Create a db connection for each one :

Mongoose :

module.exports = db_mongoose.model("Car", CarSchema);

Typegoose :

db_typegoose.model("Car", CarModel.schema, "cars");

Since this issue happened because calling model another time. Work around to this issue by wrapping your model code in try catch block. typescript code is like this -

         Import {Schema, model} from 'mongoose';
         export function user(){
              try{
                   return model('user', new Schema ({
                            FirstName: String,
                            Last name: String
                     }));
              }
             catch{
                   return model('user');
              }
         }

Similarly you can write code in js too.


I solved this by adding

mongoose.models = {}

before the line :

mongoose.model(<MODEL_NAME>, <MODEL_SCHEMA>)

Hope it solves your problem


This happened to me when I write like this:

import User from '../myuser/User.js';

However, the true path is '../myUser/User.js'


You are using mongoose.model with the same variable name "user" in check.js and insert.js.


The reason of this issue is: 

you given the model name "users" in the line 
<<<var user = mongoose.model('users' {>>> in check.js file

and again the same model name you are giving in the insert file
<<< var user = mongoose.model('users',{ >>> in insert.js

This "users" name shouldn't be same when you declare a model that should be different 
in a same project.

If you are using Serverless offline and don't want to use --skipCacheInvalidation, you can very well use:

module.exports = mongoose.models.Users || mongoose.model('Users', UsersSchema);

There is another way to throw this error.

Keep in mind that the path to the model is case sensitive.

In this similar example involving the "Category" model, the error was thrown under these conditions:

1) The require statement was mentioned in two files: ..category.js and ..index.js 2) I the first, the case was correct, in the second file it was not as follows:

category.js

enter image description here

index.js

enter image description here


The schema definition should be unique for a collection, it should not be more then one schema for a collection.


I had the same problem, reason was I defined schema an model in a JS function, they should be defined globally in a node module, not in a function.


I just have a mistake copy pasting. In one line I had same name that in other model (Ad model):

const Admin = mongoose.model('Ad', adminSchema);

Correct is:

const Admin = mongoose.model('Admin', adminSchema);

By the way, if someone have "auto-save", and use index for queries like:

**adSchema**.index({title:"text", description:"text", phone:"text", reference:"text"})

It has to delete index, and rewrite for correct model:

**adminSchema**.index({title:"text", description:"text", phone:"text", reference:"text"})

To Solve this check if the model exists before to do the creation:

if (!mongoose.models[entityDBName]) {
  return mongoose.model(entityDBName, entitySchema);
}
else {
  return mongoose.models[entityDBName];
}

You can easily solve this by doing

delete mongoose.connection.models['users'];
const usersSchema = mongoose.Schema({...});
export default mongoose.model('users', usersSchema);

ther are so many good answer but for checking we can do easier job. i mean in most popular answer there is check.js ,our guy made it so much complicated ,i suggest:

function connectToDB() {
  if (mongoose.connection.readyState === 1) {
    console.log("already connected");
    return;
  }
  mongoose.connect(
    process.env.MONGODB_URL,
    {
      useCreateIndex: true,
      useFindAndModify: false,
      useNewUrlParser: true,
      useUnifiedTopology: true,
    },
    (err) => {
      if (err) throw err;
      console.log("DB connected");
    },
  );
}

readyState== 1 means connected
so does not try to connect again
so you won't get the error
i think it because of connecting while it is connected
it is another way of connecting to db


So Another Reason why You might get this Error is if you use the same model in different files but your require path has a different case. For example in my situation I had:

require('./models/User') in one file and then in another file where I needed access to the User model I had require('./models/user').

I guess the look up for modules & mongoose is treating it as a different file. Once I made sure the case matched in both it was no longer an issue.


If you made it here it is possible that you had the same problem i did. My issue was that i was defining another model with the same name. I called my gallery and my file model "File". Darn you copy and paste!


This may give a hit for some, but I got the error as well and realized that I just misspelled the user model on importing.

wrong: const User = require('./UserModel'); correct: const User = require('./userModel');

Unbelievable but consider it.


This problem might occur if you define 2 different schema's with same Collection name


Examples related to node.js

Hide Signs that Meteor.js was Used Querying date field in MongoDB with Mongoose SyntaxError: Cannot use import statement outside a module Server Discovery And Monitoring engine is deprecated How to fix ReferenceError: primordials is not defined in node UnhandledPromiseRejectionWarning: This error originated either by throwing inside of an async function without a catch block dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.62.dylib error running php after installing node with brew on Mac internal/modules/cjs/loader.js:582 throw err DeprecationWarning: Buffer() is deprecated due to security and usability issues when I move my script to another server Please run `npm cache clean`

Examples related to mongodb

Server Discovery And Monitoring engine is deprecated Avoid "current URL string parser is deprecated" warning by setting useNewUrlParser to true MongoNetworkError: failed to connect to server [localhost:27017] on first connect [MongoNetworkError: connect ECONNREFUSED 127.0.0.1:27017] Failed to auto-configure a DataSource: 'spring.datasource.url' is not specified Failed to start mongod.service: Unit mongod.service not found db.collection is not a function when using MongoClient v3.0 MongoError: connect ECONNREFUSED 127.0.0.1:27017 MongoDB: How To Delete All Records Of A Collection in MongoDB Shell? How to resolve Nodejs: Error: ENOENT: no such file or directory How to create a DB for MongoDB container on start up?

Examples related to model

Eloquent ORM laravel 5 Get Array of ids Tensorflow: how to save/restore a model? Cannot overwrite model once compiled Mongoose AngularJS - Binding radio buttons to models with boolean values Accessing MVC's model property from Javascript MVC 4 - how do I pass model data to a partial view? How to load json into my angular.js ng-model? Check if an object exists CodeIgniter PHP Model Access "Unable to locate the model you have specified" Removing a model in rails (reverse of "rails g model Title...")

Examples related to express

UnhandledPromiseRejectionWarning: This error originated either by throwing inside of an async function without a catch block jwt check if token expired Avoid "current URL string parser is deprecated" warning by setting useNewUrlParser to true MongoNetworkError: failed to connect to server [localhost:27017] on first connect [MongoNetworkError: connect ECONNREFUSED 127.0.0.1:27017] npm notice created a lockfile as package-lock.json. You should commit this file Make Axios send cookies in its requests automatically What does body-parser do with express? SyntaxError: Unexpected token function - Async Await Nodejs Route.get() requires callback functions but got a "object Undefined" How to redirect to another page in node.js

Examples related to mongoose

Querying date field in MongoDB with Mongoose Server Discovery And Monitoring engine is deprecated Avoid "current URL string parser is deprecated" warning by setting useNewUrlParser to true Mongodb: failed to connect to server on first connect Push items into mongo array via mongoose Mongoose: findOneAndUpdate doesn't return updated document mongoError: Topology was destroyed Difference between MongoDB and Mongoose How can you remove all documents from a collection with Mongoose? E11000 duplicate key error index in mongodb mongoose