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

  1. Populate from the root with the dotted path: await doc.populate('profile.avatar')
  2. 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

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


AI-assisted analysis of Automattic/mongoose@49cdab0136 (2026-08-21). Data as JSON: /api/errors/0b98400ed8d3538f. Report an issue: GitHub.