{"record":{"id":"a3d4e0359d5274cb","repo":"Automattic/mongoose","slug":"tried-to-set-nested-object-field-path-to-ty","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/document.js","lineNumber":755,"sourceCode":"};\n\n/**\n * Init helper.\n *\n * @param {object} self document instance\n * @param {object} obj raw mongodb doc\n * @param {object} doc object we are initializing\n * @param {object} [opts] Optional Options\n * @param {boolean} [opts.setters] Call `applySetters` instead of `cast`\n * @param {string} [prefix] Prefix to add to each path\n * @api private\n */\n\nfunction init(self, obj, doc, opts, prefix) {\n  prefix = prefix || '';\n\n  if (typeof obj !== 'object' || Array.isArray(obj)) {\n    throw new ObjectExpectedError(self.$basePath, obj);\n  }\n\n  if (obj.$__ != null) {\n    obj = obj._doc;\n  }\n  const keys = Object.keys(obj);\n  const len = keys.length;\n  let schemaType;\n  let path;\n  let i;\n  const strict = self.$__.strictMode;\n  const docSchema = self.$__schema;\n  const strictRead = docSchema.options.strictRead;\n\n  for (let index = 0; index < len; ++index) {\n    i = keys[index];\n    // avoid prototype pollution\n    if (specialProperties.has(i)) {","sourceCodeStart":737,"sourceCodeEnd":773,"githubUrl":"https://github.com/Automattic/mongoose/blob/49cdab01366679723b487ecb754b38570f783289/lib/document.js#L737-L773","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":"// before — schema expects an object, data has a string\n// schema: new Schema({ nested: { sub: String } }); db doc: { nested: 'oops' }\nconst doc = await Model.findOne(); // ObjectExpectedError\n\n// after — migrate stored data to the schema shape\nawait Model.updateMany(\n  { nested: { $type: 'string' } },\n  [{ $set: { nested: { sub: '$nested' } } }]\n);\nconst doc = await Model.findOne();","handlingStrategy":"validation","validationCode":"function nestedPathsOk(schema, raw) {\n  const nested = Object.entries(schema.tree)\n    .filter(([p, t]) => raw[p] != null && t != null && typeof t === 'object' && !Array.isArray(t))\n    .map(([p]) => p);\n  return nested.every(p => typeof raw[p] === 'object');\n}\n// before doc.init(raw) on untrusted data:\nif (!nestedPathsOk(Model.schema, raw)) {\n  deadLetter(raw);\n} else {\n  doc.init(raw);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await Model.findOne({ _id });\n} catch (err) {\n  if (err.name === 'ObjectExpectedError') {\n    // stored data shape disagrees with the schema — inspect and migrate the doc\n    await quarantineDoc(_id, err.path);\n  } else {\n    throw err;\n  }\n}","preventionTips":["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"],"tags":["document","hydration","schema-mismatch","objectexpectederror","data-migration","mongoose"],"backgroundTag":"schema-data-type-mismatch","analyzedSha":"49cdab01366679723b487ecb754b38570f783289","analyzedAt":"2026-08-21T22:54:00.882Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}