Automattic/mongoose · error · Error
For your own good, Mongoose does not know how to remove an A
Error message
For your own good, Mongoose does not know how to remove an ArraySubdocument that has no _id
What it means
ArraySubdocument.prototype.$__removeFromParent() (invoked by subdoc.deleteOne()) removes the element from its parent array via parentArray.pull({ _id }). If the subdocument has no _id — typically because the array's schema was declared with { _id: false } — Mongoose has no key to pull by and refuses rather than silently removing the wrong element.
Source
Thrown at lib/types/arraySubdocument.js:101
/*!
* ignore
*/
ArraySubdocument.prototype.populate = function() {
throw new Error('Mongoose does not support calling populate() on nested ' +
'docs. Instead of `doc.arr[0].populate("path")`, use ' +
'`doc.populate("arr.0.path")`');
};
/*!
* ignore
*/
ArraySubdocument.prototype.$__removeFromParent = function() {
const _id = this._doc._id;
if (!_id) {
throw new Error('For your own good, Mongoose does not know ' +
'how to remove an ArraySubdocument that has no _id');
}
this.__parentArray.pull({ _id: _id });
};
/**
* Returns the full path to this document. If optional `path` is passed, it is appended to the full path.
*
* @param {string} [path]
* @param {boolean} [skipIndex] Skip adding the array index. For example `arr.foo` instead of `arr.0.foo`.
* @return {string}
* @api private
* @method $__fullPath
* @memberOf ArraySubdocument
* @instance
*/
ArraySubdocument.prototype.$__fullPath = function(path, skipIndex) {View on GitHub (pinned to 49cdab0136)
Solutions
- Remove { _id: false } from the subdocument schema so elements get _ids
- Or delete by value/index through the parent array: doc.subs.pull({ name: 'x' }) or doc.subs = doc.subs.filter(s => s !== target)
- For data already lacking _ids, backfill _ids before using deleteOne()
Example fix
// before
const subSchema = new Schema({ name: String }, { _id: false });
// ...
doc.subs[0].deleteOne(); // throws
// after
const subSchema = new Schema({ name: String }); // default _id: true
doc.subs[0].deleteOne(); Defensive patterns
Strategy: validation
Validate before calling
function deleteSubdoc(arr, subdoc) {
if (subdoc._id == null) {
arr.splice(arr.indexOf(subdoc), 1); // fallback by identity
return;
}
subdoc.deleteOne();
} Type guard
function canDeleteOne(subdoc) { return subdoc._id != null; } Try / catch
try { doc.subs[0].deleteOne(); } catch (err) { if (/no _id/.test(err.message)) { doc.subs = doc.subs.filter(s => s !== doc.subs[0]); } else throw err; } Prevention
- Keep default _id: true on subdocument arrays that will use deleteOne()
- Prefer parent-level pull({ ...criteria }) over element-level deleteOne for _id-less subdocs
- When ingesting legacy data, backfill element _ids before enabling element deletion
When it happens
Trigger: new Schema({ subs: [new Schema({ name: String }, { _id: false })] }) followed by doc.subs[0].deleteOne(); calling deleteOne() on any array subdocument whose _id is missing.
Common situations: Disabling _id on subdocument arrays to save storage or match legacy data, then using element-level deleteOne(); loading documents from collections that never stored element _ids.
Related errors
- Aggregate.prototype.exec() no longer accepts a callback
- Expected path "${path}" to be populated
- Infinite subdocument loop: subdoc with _id ${doc._id} is a p
- Document deleteOne pre hooks cannot overwrite arguments
- Cast to embedded failed for value "${value}" (type ${valueTy
AI-assisted analysis of Automattic/mongoose@49cdab0136 (2026-08-21).
Data as JSON: /api/errors/c011c876bb06336e.
Report an issue: GitHub.