Automattic/mongoose · error · TypeError

First argument to `Model` constructor must be an object, **n

Error message

First argument to `Model` constructor must be an object, **not** a string. Make sure you're calling `mongoose.model()`, not `mongoose.Model()`.

What it means

Companion guard in the Model constructor: the first argument must be a document object, not a string. Calling mongoose.Model('User') or new mongoose.Model('User', ...) — using the Model constructor where the mongoose.model(name, schema) registry function is meant — throws this TypeError immediately instead of producing a broken object.

Source

Thrown at lib/model.js:139

 * @param {object} [options] optional object containing the options for the document.
 * @param {boolean} [options.defaults=true] if `false`, skip applying default values to this document.
 * @param {boolean} [options.skipId=false] By default, Mongoose document if one is not provided and the document's schema does not override Mongoose's default `_id`. Set `skipId` to `true` to skip this generation step.
 * @inherits Document https://mongoosejs.com/docs/api/document.html
 * @event `error`: If listening to this event, 'error' is emitted when a document was saved and an `error` occurred. If not listening, the event bubbles to the connection used to create this Model.
 * @event `index`: Emitted after `Model#ensureIndexes` completes. If an error occurred it is passed with the event.
 * @event `index-single-start`: Emitted when an individual index starts within `Model#ensureIndexes`. The fields and options being used to build the index are also passed with the event.
 * @event `index-single-done`: Emitted when an individual index finishes within `Model#ensureIndexes`. If an error occurred it is passed with the event. The fields, options, and index name are also passed.
 * @api public
 */

function Model(doc, fields, options) {
  if (fields instanceof Schema) {
    throw new TypeError('2nd argument to `Model` constructor must be a POJO or string, ' +
      '**not** a schema. Make sure you\'re calling `mongoose.model()`, not ' +
      '`mongoose.Model()`.');
  }
  if (typeof doc === 'string') {
    throw new TypeError('First argument to `Model` constructor must be an object, ' +
      '**not** a string. Make sure you\'re calling `mongoose.model()`, not ' +
      '`mongoose.Model()`.');
  }
  Document.call(this, doc, fields, options);
}

/**
 * Inherits from Document.
 *
 * All Model.prototype features are available on
 * top level (non-sub) documents.
 * @api private
 */

Object.setPrototypeOf(Model.prototype, Document.prototype);
Model.prototype.$isMongooseModelPrototype = true;

/**

View on GitHub (pinned to 49cdab0136)

Solutions

  1. Use mongoose.model('User', userSchema) to register and compile the model
  2. Keep an imported Model only for typing/extends (class User extends Model<User>), never as a callable factory

Example fix

// before
import { Model, Schema } from 'mongoose';
const User = Model('User', userSchema); // TypeError

// after
import mongoose from 'mongoose';
const User = mongoose.model('User', userSchema);
Defensive patterns

Strategy: type-guard

Validate before calling

// Guard a factory helper against string-first Model calls
function registerModel(name, schema) {
  if (typeof name !== 'string' || !(schema instanceof mongoose.Schema)) {
    throw new TypeError('Use mongoose.model(name, schema)');
  }
  return mongoose.model(name, schema);
}

Type guard

const isDocumentInput = (doc) => doc != null && typeof doc === 'object' && !Array.isArray(doc);

Try / catch

try {
  const M = mongoose.Model('User', schema);
} catch (err) {
  if (err instanceof TypeError && /First argument to `Model`/.test(err.message)) {
    // use mongoose.model('User', schema) instead
  } else throw err;
}

Prevention

When it happens

Trigger: const User = mongoose.Model('User', userSchema) or new mongoose.Model('User'); confusion between mongoose.model (lowercase, factory/registry) and mongoose.Model (uppercase, base class), often after `import { Model } from 'mongoose'`.

Common situations: Autocomplete picking Model over model; tutorials and snippets mixing the two names; refactors that rename the mongoose import and leave a bare Model(...) call.

Related errors


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