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
ObjectExpectedError thrown by SchemaSubdocument.cast when a non-null value that is not an object (a string, number, boolean) or is an array is assigned to a single-nested ('embedded') path during a document set (not on init from the database). Mongoose requires a plain object it can cast into the subschema.
Source
Thrown at lib/schema/subdocument.js:183
Object.defineProperty(SchemaSubdocument.prototype, '$conditionalHandlers', {
enumerable: false,
value: $conditionalHandlers
});
/**
* Casts contents
*
* @param {object} value
* @api private
*/
SchemaSubdocument.prototype.cast = function(val, doc, init, priorVal, options) {
if (val?.$isSingleNested && val.parent === doc) {
return val;
}
if (!init && val != null && (typeof val !== 'object' || Array.isArray(val))) {
throw new ObjectExpectedError(this.path, val);
}
const discriminatorKeyPath = this.schema.path(this.schema.options.discriminatorKey);
const defaultDiscriminatorValue = discriminatorKeyPath == null ? null : discriminatorKeyPath.getDefault(doc);
const Constructor = getConstructor(this.Constructor, val, defaultDiscriminatorValue);
let subdoc;
// Only pull relevant selected paths and pull out the base path
const parentSelected = doc?.$__?.selected;
const path = this.path;
const selected = parentSelected == null ? null : Object.keys(parentSelected).reduce((obj, key) => {
if (key.startsWith(path + '.')) {
obj = obj || {};
obj[key.substring(path.length + 1)] = parentSelected[key];
}
return obj;
}, null);View on GitHub (pinned to 49cdab0136)
Solutions
- Assign a plain object matching the subschema: `doc.child = { name: 'A' }`
- JSON.parse the value first if the source sends serialized JSON
- If a list was intended, declare the path as `type: [childSchema]` instead of a single subdocument
Example fix
// before
doc.child = '{"name":"A"}'; // string, throws
// after
doc.child = JSON.parse('{"name":"A"}'); // plain object Defensive patterns
Strategy: validation
Validate before calling
function isPlainObject(v) {
return v != null && typeof v === 'object' && !Array.isArray(v);
}
if (!isPlainObject(payload.child)) payload.child = JSON.parse(payload.child); // or reject Type guard
const isPlainObject = v => v != null && typeof v === 'object' && !Array.isArray(v);
Try / catch
try {
doc.child = value;
} catch (err) {
if (err.name === 'ObjectExpectedError') {
// value was a primitive/array where an object was expected; reject or coerce
} else throw err;
} Prevention
- Validate request payloads with zod/joi so nested fields must be objects before reaching models
- JSON.parse serialized nested values at the API boundary, not inside mongoose
- If lists are expected, declare the path as an array of subdocuments from the start
When it happens
Trigger: `doc.child = 'oops'` where `child` is defined as `new Schema({ name: String })`; `Model.updateOne({}, { $set: { child: 42 } })`; assigning a JSON.stringify'd string where the object was expected.
Common situations: API payloads where the nested field arrives as stringified JSON; form data always being strings; assigning an array to a single-nested field when an array-of-subdocs schema was intended.
Related errors
- Cast to embedded failed for value "${value}" (type ${valueTy
- Cast to string failed for value "${value}" (type ${valueType
- Cannot create use schema for property "${path}" because the
- Cast to Embedded failed for value "${value}" (type ${valueTy
- Cast to UUID failed for value "${value}" (type ${valueType})
AI-assisted analysis of Automattic/mongoose@49cdab0136 (2026-08-21).
Data as JSON: /api/errors/13c71441cd9b8f8d.
Report an issue: GitHub.