Automattic/mongoose · error · CastError
Cast to Embedded failed for value "${value}" (type ${valueTy
Error message
Cast to Embedded failed for value "${value}" (type ${valueType}) at path "${path}" What it means
When casting a query/update value into a single-nested subdocument, mongoose runs `new Constructor(val)`. Any failure that is not already a CastError is wrapped as `Cast to Embedded failed ... at path` (gh-6803) so callers always get a CastError; the underlying error is preserved on `err.reason`.
Source
Thrown at lib/schema/subdocument.js:264
}
const Constructor = getConstructor(this.Constructor, val);
if (val instanceof Constructor) {
return val;
}
if (this.options.runSetters) {
val = this._applySetters(val, context);
}
const overrideStrict = options?.strict ?? void 0;
try {
val = new Constructor(val, overrideStrict);
} catch (error) {
// Make sure we always wrap in a CastError (gh-6803)
if (!(error instanceof CastError)) {
throw new CastError('Embedded', val, this.path, error, this);
}
throw error;
}
return val;
};
/**
* Async validation on this single nested doc.
*
* @api public
*/
SchemaSubdocument.prototype.doValidate = async function doValidate(value, scope, options) {
const Constructor = getConstructor(this.Constructor, value);
if (value && !(value instanceof Constructor)) {
value = new Constructor(value, null, scope?.$__ != null ? scope : null);
}View on GitHub (pinned to 49cdab0136)
Solutions
- Pass a plain object (or query the subfield with a dotted path) instead of a primitive
- Inspect `err.reason` and the original message to find the real failure inside the subschema
- Fix or make exception-safe any custom setter/transform on the subschema that throws non-CastError errors
- Cast the value yourself (`new Subdoc(value)`) inside try/catch to surface the raw error during development
Example fix
// before
Model.find({ nested: 'x' }); // throws Cast to Embedded failed
// after
Model.find({ 'nested.name': 'x' }); // query the subfield directly Defensive patterns
Strategy: try-catch
Validate before calling
function isCastableSubdocValue(v) {
return v == null || (typeof v === 'object' && !Array.isArray(v));
} Type guard
const isCastableSubdocValue = v => v == null || (typeof v === 'object' && !Array.isArray(v));
Try / catch
try {
const docs = await Model.find({ nested: raw });
} catch (err) {
if (err instanceof mongoose.Error.CastError && err.kind === 'Embedded') {
const root = err.reason; // underlying constructor/setter failure
// reject the request payload and include err.path + root.message in diagnostics
} else throw err;
} Prevention
- Always read `err.reason` on Embedded CastErrors — the real cause is nested there (gh-6803)
- Query subfields with dotted paths instead of passing whole values for the embedded path
- Make custom setters exception-safe or rethrow CastErrors so wrapping stays informative
When it happens
Trigger: `Model.find({ nested: 'not-an-object' })` where the value cannot be constructed into the subschema; custom setters on the subschema that throw TypeErrors during construction; `$set` updates with values the subdocument constructor rejects.
Common situations: Passing primitives where objects are expected in filters; discriminator construction mismatches; bugs in custom setters that only surface during query casting.
Related errors
- Query filter must be an object, got an array ${util.inspect(
- Cast to Array failed for value "${value}" at path "${path}"
- Cast to Object failed for value "${value}" at path "${path}.
- Cast to embedded failed for value "${value}" (type ${valueTy
- Cast to number failed for value "${value}" (type ${valueType
AI-assisted analysis of Automattic/mongoose@49cdab0136 (2026-08-21).
Data as JSON: /api/errors/f5c5a73c7cc98552.
Report an issue: GitHub.