Automattic/mongoose · error · ObjectParameterError

Parameter "doc" to insertOne() must be an object, got "${doc

Error message

Parameter "doc" to insertOne() must be an object, got "${doc}" (type ${typeof doc})

What it means

Model.insertOne() requires its first argument to be a non-null object (POJO or Mongoose Document). The guard `doc == null || typeof doc !== 'object'` throws ObjectParameterError, whose message embeds the received value and its typeof. Note the check happens before discriminator resolution and before any casting, so nothing reaches the database.

Source

Thrown at lib/model.js:2878

 *
 *     // Insert one new `Character` document
 *     const character = await Character.insertOne({ name: 'Jean-Luc Picard' });
 *     character.name; // 'Jean-Luc Picard'
 *
 *     // Create a new character within a transaction.
 *     await Character.insertOne({ name: 'Jean-Luc Picard' }, { session });
 *
 * @param {object|Document} doc Document to insert, as a POJO or Mongoose document
 * @param {object} [options] Options passed down to `save()`.
 * @return {Promise<Document>} resolves to the saved document
 * @api public
 */

Model.insertOne = async function insertOne(doc, options) {
  _checkContext(this, 'insertOne');

  if (doc == null || typeof doc !== 'object') {
    throw new ObjectParameterError(doc, 'doc', 'insertOne');
  }

  const discriminatorKey = this.schema.options.discriminatorKey;
  const Model = this.discriminators && doc[discriminatorKey] != null ?
    this.discriminators[doc[discriminatorKey]] || getDiscriminatorByValue(this.discriminators, doc[discriminatorKey]) :
    this;
  if (Model == null) {
    throw new MongooseError(
      `Discriminator "${doc[discriminatorKey]}" not found for model "${this.modelName}"`
    );
  }
  if (!(doc instanceof Model)) {
    doc = new Model(doc);
  }

  return await doc.$save(options);
};

View on GitHub (pinned to 49cdab0136)

Solutions

  1. Pass a plain object or document: await Model.insertOne({ name: 'x' })
  2. If the input may be a JSON string, parse it first: typeof doc === 'string' ? JSON.parse(doc) : doc
  3. Validate at the trust boundary (route handler / message consumer) that the payload is an object before forwarding to insertOne
  4. In TypeScript, type the parameter so the compiler rejects string/number/null

Example fix

// before
const doc = await req.redis.get('user'); // returns a JSON string
await User.insertOne(doc); // throws: must be an object, got "{...}" (type string)

// after
const raw = await req.redis.get('user');
await User.insertOne(JSON.parse(raw));
Defensive patterns

Strategy: type-guard

Validate before calling

if (doc == null || typeof doc !== 'object') {
  throw new TypeError(`insertOne: expected object, got ${typeof doc}`);
}
await Model.insertOne(doc);

Type guard

function isInsertableDoc(v) {
  return v != null && typeof v === 'object' && !Array.isArray(v);
}
// TypeScript:
// const isInsertableDoc = (v: unknown): v is Record<string, unknown> | mongoose.Document =>
//   v != null && typeof v === 'object' && !Array.isArray(v);
if (!isInsertableDoc(doc)) throw new TypeError('insertOne: doc must be an object');
await Model.insertOne(doc);

Try / catch

try {
  await Model.insertOne(payload);
} catch (err) {
  if (err.name === 'ObjectParameterError') { /* upstream sent a non-object (e.g. unparsed JSON) */ }
  else throw err;
}

Prevention

When it happens

Trigger: Model.insertOne('foo'), insertOne(42), insertOne(null), or insertOne(undefined). Classic source: forgetting JSON.parse on a request body or queue message, so a JSON string is passed instead of an object.

Common situations: Passing unparsed JSON strings from HTTP bodies, Redis/Kafka messages, or env vars; passing an id instead of a document; default parameters that evaluate to undefined when an upstream field is missing.

Understand the failure class

Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.

Related errors


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