Automattic/mongoose · error · MissingSchemaError

Schema hasn't been registered for model "${name}". Use mongo

Error message

Schema hasn't been registered for model "${name}".
Use mongoose.model(name, schema)

What it means

conn.model(name) with a single argument is a pure lookup against models already compiled on THIS connection. If nothing is registered under that name, Mongoose throws MissingSchemaError ('Schema hasn't been registered for model ...') at lib/connection.js:1509 — it cannot invent a schema, so the model must have been registered first, or the name/connection is wrong.

Source

Thrown at lib/connection.js:1509

    // Errors handled internally, so safe to ignore error
    model.init().catch(function $modelInitNoop() {});

    return model;
  }

  if (this.models[name] && collection) {
    // subclassing current model with alternate collection
    model = this.models[name];
    schema = model.prototype.schema;
    const sub = model.__subclass(this, schema, collection);
    // do not cache the sub model
    return sub;
  }

  if (arguments.length === 1) {
    model = this.models[name];
    if (!model) {
      throw new MongooseError.MissingSchemaError(name);
    }
    return model;
  }

  if (!model) {
    throw new MongooseError.MissingSchemaError(name);
  }

  if (this === model.prototype.db
      && (!collection || collection === model.collection.name)) {
    // model already uses this connection.

    // only the first model with this name is cached to allow
    // for one-offs with custom collection names etc.
    if (!this.models[name]) {
      this.models[name] = model;
    }

View on GitHub (pinned to 49cdab0136)

Solutions

  1. Register first on the same connection: conn.model('User', userSchema), then look up
  2. Check what exists: console.log(conn.modelNames()) before the lookup
  3. Use the right registry: mongoose.model('User') for the default connection, conn.model('User') for a custom connection — they are separate
  4. Fix casing/typos; model names are case-sensitive

Example fix

// before
const conn = mongoose.createConnection(uri);
const User = conn.model('User'); // MissingSchemaError: separate registry

// after
const User = conn.model('User', userSchema); // register on this connection
// or, if registered globally: mongoose.model('User')
Defensive patterns

Strategy: validation

Validate before calling

if (!conn.modelNames().includes('User')) {
  conn.model('User', userSchema); // register before lookup
}
const User = conn.model('User');

Try / catch

let User;
try {
  User = conn.model('User');
} catch (err) {
  if (err instanceof mongoose.Error.MissingSchemaError) {
    User = conn.model('User', userSchema); // first caller registers
  } else {
    throw err;
  }
}

Prevention

When it happens

Trigger: conn.model('User') before conn.model('User', userSchema) has run; a case typo ('user' vs 'User' — names are case-sensitive); a model registered on a different connection (mongoose.model on the default connection vs a createConnection instance) and looked up on this one.

Common situations: Multi-connection / multi-tenant apps where models are registered per connection; import-order bugs where a route executes before the model file; mixing mongoose.model() and conn.model() registries.

Related errors


AI-assisted analysis of Automattic/mongoose@49cdab0136 (2026-08-21). Data as JSON: /api/errors/408f3428ffd1d83b. Report an issue: GitHub.