Automattic/mongoose · error · Error
Mongoose does not support calling populate() on nested docs.
Error message
Mongoose does not support calling populate() on nested docs. Instead of `doc.nested.populate("path")`, use `doc.populate("nested.path")` What it means
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.
Source
Thrown at lib/types/subdocument.js:384
Subdocument.prototype.deleteOne = function deleteOne(options) {
registerRemoveListener(this);
// If removing entire doc, no need to remove subdoc
if (!options?.noop) {
this.$__removeFromParent();
const owner = this.ownerDocument();
owner.$__.removedSubdocs = owner.$__.removedSubdocs || [];
owner.$__.removedSubdocs.push(this);
}
};
/*!
* ignore
*/
Subdocument.prototype.populate = function() {
throw new Error('Mongoose does not support calling populate() on nested ' +
'docs. Instead of `doc.nested.populate("path")`, use ' +
'`doc.populate("nested.path")`');
};
/**
* Helper for console.log
*
* @api public
*/
Subdocument.prototype.inspect = function() {
return this.toObject();
};
if (util.inspect.custom) {
// Avoid Node deprecation warning DEP0079
Subdocument.prototype[util.inspect.custom] = Subdocument.prototype.inspect;
}View on GitHub (pinned to 49cdab0136)
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'])
Example fix
// before
doc.profile.populate('avatar');
// after
await doc.populate('profile.avatar'); Defensive patterns
Strategy: type-guard
Validate before calling
function populateNested(root, nestedPath, subPath) {
if (!nestedPath || typeof nestedPath !== 'string') throw new TypeError('nestedPath required');
return root.populate(`${nestedPath}.${subPath}`);
} Type guard
function isRootDocument(doc) { return doc.$parent == null || doc.$parent() == null; } Try / catch
try { nested.populate('ref'); } catch (err) { if (/populate\(\) on nested docs/.test(err.message)) return rootDoc.populate(`nested.ref`); throw err; } Prevention
- 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
When it happens
Trigger: doc.nested.populate('user') where doc.nested is a single nested subdocument; const inner = doc.profile; inner.populate('avatar').
Common situations: 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.
Related errors
- Expected path "${path}" to be populated
- Cannot manually populate single nested subdoc underneath Map
- Invalid addFields() argument. Must be an object
- Aggregate.prototype.exec() no longer accepts a callback
- `refPath` must be a string or a function that returns a stri
AI-assisted analysis of Automattic/mongoose@49cdab0136 (2026-08-21).
Data as JSON: /api/errors/0b98400ed8d3538f.
Report an issue: GitHub.