{"record":{"id":"13c71441cd9b8f8d","repo":"Automattic/mongoose","slug":"tried-to-set-nested-object-field-path-to-ty-13c714","errorCode":null,"errorMessage":"Tried to set nested object field `${path}` to ${typeDescription} `${val}`","messagePattern":"Tried to set nested object field `(.+?)` to (.+?) `(.+?)`","errorType":"exception","errorClass":"ObjectExpectedError","httpStatus":null,"severity":"error","filePath":"lib/schema/subdocument.js","lineNumber":183,"sourceCode":"Object.defineProperty(SchemaSubdocument.prototype, '$conditionalHandlers', {\n  enumerable: false,\n  value: $conditionalHandlers\n});\n\n/**\n * Casts contents\n *\n * @param {object} value\n * @api private\n */\n\nSchemaSubdocument.prototype.cast = function(val, doc, init, priorVal, options) {\n  if (val?.$isSingleNested && val.parent === doc) {\n    return val;\n  }\n\n  if (!init && val != null && (typeof val !== 'object' || Array.isArray(val))) {\n    throw new ObjectExpectedError(this.path, val);\n  }\n\n  const discriminatorKeyPath = this.schema.path(this.schema.options.discriminatorKey);\n  const defaultDiscriminatorValue = discriminatorKeyPath == null ? null : discriminatorKeyPath.getDefault(doc);\n  const Constructor = getConstructor(this.Constructor, val, defaultDiscriminatorValue);\n\n  let subdoc;\n\n  // Only pull relevant selected paths and pull out the base path\n  const parentSelected = doc?.$__?.selected;\n  const path = this.path;\n  const selected = parentSelected == null ? null : Object.keys(parentSelected).reduce((obj, key) => {\n    if (key.startsWith(path + '.')) {\n      obj = obj || {};\n      obj[key.substring(path.length + 1)] = parentSelected[key];\n    }\n    return obj;\n  }, null);","sourceCodeStart":165,"sourceCodeEnd":201,"githubUrl":"https://github.com/Automattic/mongoose/blob/49cdab01366679723b487ecb754b38570f783289/lib/schema/subdocument.js#L165-L201","documentation":"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.","triggerScenarios":"`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.","commonSituations":"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.","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"],"exampleFix":"// before\ndoc.child = '{\"name\":\"A\"}'; // string, throws\n\n// after\ndoc.child = JSON.parse('{\"name\":\"A\"}'); // plain object","handlingStrategy":"validation","validationCode":"function isPlainObject(v) {\n  return v != null && typeof v === 'object' && !Array.isArray(v);\n}\nif (!isPlainObject(payload.child)) payload.child = JSON.parse(payload.child); // or reject","typeGuard":"const isPlainObject = v => v != null && typeof v === 'object' && !Array.isArray(v);","tryCatchPattern":"try {\n  doc.child = value;\n} catch (err) {\n  if (err.name === 'ObjectExpectedError') {\n    // value was a primitive/array where an object was expected; reject or coerce\n  } else throw err;\n}","preventionTips":["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"],"tags":["mongoose","subdocument","cast","assignment","schema"],"backgroundTag":"type-mismatch-assignment","analyzedSha":"49cdab01366679723b487ecb754b38570f783289","analyzedAt":"2026-08-21T22:54:00.882Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}