Automattic/mongoose · error · ObjectExpectedError
Tried to set nested object field `${path}` to ${typeDescript
Error message
Tried to set nested object field `${path}` to ${typeDescription} `${val}` What it means
During hydration Mongoose walks the schema's nested paths and expects an object at every nested level. ObjectExpectedError is thrown when the raw document stores a non-object (string, number, array) where the schema declares a nested sub-document; the message names the path, the offending type and the value.
Source
Thrown at lib/document.js:755
};
/**
* Init helper.
*
* @param {object} self document instance
* @param {object} obj raw mongodb doc
* @param {object} doc object we are initializing
* @param {object} [opts] Optional Options
* @param {boolean} [opts.setters] Call `applySetters` instead of `cast`
* @param {string} [prefix] Prefix to add to each path
* @api private
*/
function init(self, obj, doc, opts, prefix) {
prefix = prefix || '';
if (typeof obj !== 'object' || Array.isArray(obj)) {
throw new ObjectExpectedError(self.$basePath, obj);
}
if (obj.$__ != null) {
obj = obj._doc;
}
const keys = Object.keys(obj);
const len = keys.length;
let schemaType;
let path;
let i;
const strict = self.$__.strictMode;
const docSchema = self.$__schema;
const strictRead = docSchema.options.strictRead;
for (let index = 0; index < len; ++index) {
i = keys[index];
// avoid prototype pollution
if (specialProperties.has(i)) {View on GitHub (pinned to 49cdab0136)
Solutions
- Migrate the data so the path holds an object: Model.updateMany({ nested: { $type: 'string' } }, [{ $set: { nested: { sub: '$nested' } } }])
- If the flat value is legitimate, change the schema: declare the path with its scalar type or use Schema.Types.Mixed
- When importing untrusted data, validate nested paths before hydrating and route bad docs to a repair/dead-letter queue
Example fix
// before — schema expects an object, data has a string
// schema: new Schema({ nested: { sub: String } }); db doc: { nested: 'oops' }
const doc = await Model.findOne(); // ObjectExpectedError
// after — migrate stored data to the schema shape
await Model.updateMany(
{ nested: { $type: 'string' } },
[{ $set: { nested: { sub: '$nested' } } }]
);
const doc = await Model.findOne(); Defensive patterns
Strategy: validation
Validate before calling
function nestedPathsOk(schema, raw) {
const nested = Object.entries(schema.tree)
.filter(([p, t]) => raw[p] != null && t != null && typeof t === 'object' && !Array.isArray(t))
.map(([p]) => p);
return nested.every(p => typeof raw[p] === 'object');
}
// before doc.init(raw) on untrusted data:
if (!nestedPathsOk(Model.schema, raw)) {
deadLetter(raw);
} else {
doc.init(raw);
} Try / catch
try {
await Model.findOne({ _id });
} catch (err) {
if (err.name === 'ObjectExpectedError') {
// stored data shape disagrees with the schema — inspect and migrate the doc
await quarantineDoc(_id, err.path);
} else {
throw err;
}
} Prevention
- Run a shape audit (field $type checks) against existing collections after schema refactors
- Migrate stored data in the same release that changes a scalar path into a nested object
- Use Schema.Types.Mixed for paths that legitimately hold heterogeneous shapes
When it happens
Trigger: Schema new Schema({ nested: { sub: String } }) while the stored document holds nested: 'oops' (or a number/array); the error surfaces when hydrating via findOne/find or doc.init(raw).
Common situations: Schema refactors that turned a scalar field into a nested object without a data migration; hand-edited or imported data; another writer (legacy app, different ORM) storing flat values into the same collection.
Related errors
- Parameter "doc" to init() must be an object, got "${doc}" (t
- Aggregate `near()` argument must have a `near` property
- Aggregate `near()` argument has invalid coordinates, got "${
- Parameter "obj" to Document() must be an object, got "${obj}
- Field `${path}` is not in schema and strictRead is set to th
AI-assisted analysis of Automattic/mongoose@49cdab0136 (2026-08-21).
Data as JSON: /api/errors/a3d4e0359d5274cb.
Report an issue: GitHub.