{"record":{"id":"0b98400ed8d3538f","repo":"Automattic/mongoose","slug":"mongoose-does-not-support-calling-populate-on-ne-0b9840","errorCode":null,"errorMessage":"Mongoose does not support calling populate() on nested docs. Instead of `doc.nested.populate(\"path\")`, use `doc.populate(\"nested.path\")`","messagePattern":"Mongoose does not support calling populate\\(\\) on nested docs\\. Instead of `doc\\.nested\\.populate\\(\"path\"\\)`, use `doc\\.populate\\(\"nested\\.path\"\\)`","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/types/subdocument.js","lineNumber":384,"sourceCode":"Subdocument.prototype.deleteOne = function deleteOne(options) {\n  registerRemoveListener(this);\n\n  // If removing entire doc, no need to remove subdoc\n  if (!options?.noop) {\n    this.$__removeFromParent();\n\n    const owner = this.ownerDocument();\n    owner.$__.removedSubdocs = owner.$__.removedSubdocs || [];\n    owner.$__.removedSubdocs.push(this);\n  }\n};\n\n/*!\n * ignore\n */\n\nSubdocument.prototype.populate = function() {\n  throw new Error('Mongoose does not support calling populate() on nested ' +\n    'docs. Instead of `doc.nested.populate(\"path\")`, use ' +\n    '`doc.populate(\"nested.path\")`');\n};\n\n/**\n * Helper for console.log\n *\n * @api public\n */\n\nSubdocument.prototype.inspect = function() {\n  return this.toObject();\n};\n\nif (util.inspect.custom) {\n  // Avoid Node deprecation warning DEP0079\n  Subdocument.prototype[util.inspect.custom] = Subdocument.prototype.inspect;\n}","sourceCodeStart":366,"sourceCodeEnd":402,"githubUrl":"https://github.com/Automattic/mongoose/blob/49cdab01366679723b487ecb754b38570f783289/lib/types/subdocument.js#L366-L402","documentation":"Subdocument.prototype.populate() (single nested, not array) is intentionally unimplemented and always throws. Populate needs the root document's db connection and populate context, so Mongoose requires calling populate on the top-level document using the dotted path through the nested doc.","triggerScenarios":"doc.nested.populate('user') where doc.nested is a single nested subdocument; const inner = doc.profile; inner.populate('avatar').","commonSituations":"Code holding a reference to a nested object (profile, address) that tries to hydrate its refs directly; refactoring top-level populate calls into nested helpers.","solutions":["Populate from the root with the dotted path: await doc.populate('profile.avatar')","Populate multiple nested refs at once: await doc.populate(['profile.avatar', 'profile.settings'])"],"exampleFix":"// before\ndoc.profile.populate('avatar');\n// after\nawait doc.populate('profile.avatar');","handlingStrategy":"type-guard","validationCode":"function populateNested(root, nestedPath, subPath) {\n  if (!nestedPath || typeof nestedPath !== 'string') throw new TypeError('nestedPath required');\n  return root.populate(`${nestedPath}.${subPath}`);\n}","typeGuard":"function isRootDocument(doc) { return doc.$parent == null || doc.$parent() == null; }","tryCatchPattern":"try { nested.populate('ref'); } catch (err) { if (/populate\\(\\) on nested docs/.test(err.message)) return rootDoc.populate(`nested.ref`); throw err; }","preventionTips":["Route all populate calls through the root document with dotted paths","Wrap subdoc references in helpers that remember their root instead of calling populate directly","Code-review for '.populate(' on anything obtained from a document property"],"tags":["mongoose","populate","subdocument","single-nested"],"backgroundTag":"unsupported-populate-call","analyzedSha":"49cdab01366679723b487ecb754b38570f783289","analyzedAt":"2026-08-21T22:54:00.882Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}