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
- Pass a plain object or document: await Model.insertOne({ name: 'x' })
- If the input may be a JSON string, parse it first: typeof doc === 'string' ? JSON.parse(doc) : doc
- Validate at the trust boundary (route handler / message consumer) that the payload is an object before forwarding to insertOne
- 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
- Parse JSON at the boundary and type the parsed value before passing it on
- Validate request bodies with a schema validator (zod/joi) that enforces object types
- Unit-test message consumers with raw string payloads to catch missing JSON.parse
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
- Invalid addFields() argument. Must be an object
- Parameter "obj" to Document() must be an object, got "${obj}
- Invalid select() argument. Must be string or object.
- Options must be an object, got "${options}"
- sort() takes at most 2 arguments
AI-assisted analysis of Automattic/mongoose@49cdab0136 (2026-08-21).
Data as JSON: /api/errors/89ac1ff4bbd8c1af.
Report an issue: GitHub.