Mongoose: MissingSchemaError: Schema hasn't been registered for model

Created on 26 Jun 2015  路  18Comments  路  Source: Automattic/mongoose

Error:

/var/www/html/noodetest/node_modules/mongoose/lib/index.js:329
      throw new mongoose.Error.MissingSchemaError(name);
            ^
MissingSchemaError: Schema hasn't been registered for model "User".
Use mongoose.model(name, schema)
    at Mongoose.model (/var/www/html/noodetest/node_modules/mongoose/lib/index.js:329:13)
    at Object.<anonymous> (/var/www/html/noodetest/app/models/rrss.js:3:29)
    at Module._compile (module.js:460:26)
    at Object.Module._extensions..js (module.js:478:10)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Module.require (module.js:365:17)
    at require (module.js:384:17)
    at Object.<anonymous> (/var/www/html/noodetest/server.js:36:14)
    at Module._compile (module.js:460:26)
    at Object.Module._extensions..js (module.js:478:10)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Function.Module.runMain (module.js:501:10)
    at startup (node.js:129:16)
    at node.js:814:3

Model user:

var mongoose     = require('mongoose'),
    Schema       = mongoose.Schema,
    Social       = mongoose.model('Social');

var userSchema   = new mongoose.Schema({
    name: { type:  Schema.Types.String, required: true },
    nick: { type:  Schema.Types.String, required: true },
    bio: { type:  Schema.Types.String, required: true },
    avatar: { type:  Schema.Types.String, required: false },
    rrss: [
        {
            type: Schema.Types.ObjectId, ref: 'Social'
        }
    ]
});

module.exports = mongoose.model('User', userSchema);

Model social:

var mongoose     = require('mongoose'),
    Schema       = mongoose.Schema,
    User         = mongoose.model('User');

var socialSchema   = new mongoose.Schema({
    twitter: { type:  Schema.Types.String },
    github: { type:  Schema.Types.String },
    web: { type:  Schema.Types.String },
    user_id: [
        {
            type: Schema.Types.String, ref: 'User'
        }
    ]
});

module.exports = mongoose.model('Social', socialSchema);
// Load models
var Social = require('./app/models/rrss'),
    User   = require('./app/models/user'),
    Schema = mongoose.Schema;

What i miss?

help

Most helpful comment

You called require() on the social schema first, which attempts to compile the 'Social' model that references a 'User' model that isn't defined until later. Since you have circular refs, there's no way for mongoose to successfully compile these models, which is fine since circular refs are often indicative of poor schema design choices.

All 18 comments

You called require() on the social schema first, which attempts to compile the 'Social' model that references a 'User' model that isn't defined until later. Since you have circular refs, there's no way for mongoose to successfully compile these models, which is fine since circular refs are often indicative of poor schema design choices.

Oh, i see... Well, thanks :)

@vkarpov15

Can you please explain a little more?
Did you mean that using refs is not a good choice?

I have 2 different servers to hold User and Product databases.
Each User has a list of product ids (using mongoose's refs) and I'm getting the same error...
Do i have to rethink my implementation?

Using refs is reasonable, usually having two models reference each other is unnecessary though. Either a user should have a list of products or a product has a list of users, but rarely necessary to have both.

@vkarpov15 I agree that _sometimes_ models that bi-directionally reference each other reflects poor design choices, but other times it's just a necessary evil. Is there a recommended way of handling this? If so, could it be added to the docs? Or better yet, supported by the library.

@ajsharp I don't know of any such cases off the top of my head. But, assuming there is such a case, there's nothing stopping you from having an array of refs in two different schemas that point to each other, I don't really see how adding that to the docs would help.

i have the same problem, can you explain that more how can i get ride of this error?

@zahrajoonjafari it's difficult to help without seeing your code. Please either join us in one of the following communities:

Slack
StackOverflow
Gitter.im

or open a new issue with a minimally complete code example that reproduces the problem you're having.

It would be good to understand how to get around this problem of having two models that both require each other. I would have thought that the nature of using a document database such as MongoDB should facilitate data de-normalisation. If this is the case, then I would think it quite common to have models that require each other (?)

@joetidee there are ways to "have models that require each other", but it depends on specifically what you mean by "require" - do you mean explicit Node.js require()? Perhaps you can clarify with a code sample?

An example would be where I have Item-model.js which uses the User model:
const User = mongoose.model('User');

and where I have user-model.js which uses the Item model:
const Item = mongoose.model('Item');
I am currently loading these model files when my express server starts:

require('./user-model.js');
require('./item-model.js');

This causes a MissingSchemaError error to be thrown.

How do you use itemModel in user-model.js ? Sounds like you could benefit from exporting schemas rather than models

UserSchema.statics.foo = async function () {
  ...
  const result = await Item.bar();
  ...
};

Ah, that's right, that has been a pain point in the past for me too. Try this.db.model('Item').bar() instead. That's how mongoose generally works around circular require() calls with models.

Thank you. Would e great to post your answer here to help other too:
https://stackoverflow.com/questions/52677446/mongoose-circular-model-reference

Hi! I have the same problem. Anybody have idea how to solve this?

@MaxVinogradov check the stack trace and make sure any model names you're referencing are already declared. If that doesn't work, post some code samples here and we will help out.

In case people still encounter this problem, make sure you reference the MODEL as it is in mongoDB database. In my case i had a folder called models with User.js and Item.js, but the schema name on mongoDB is actually users and items. I referenced User and Item instead of schema name.
So, make sure you reference
users
from
const User = mongoose.model('users', UserSchema);

Was this page helpful?
0 / 5 - 0 ratings