Automattic/mongoose · error · MongooseError

No _id found on document!

Error message

No _id found on document!

What it means

Document-level delete (doc.deleteOne()) builds its filter from the document's _id via $__where; if the in-memory document has no _id the query would match nothing (or be ambiguous), so Mongoose throws 'No _id found on document!'. It means the document object itself lacks _id — schema disabled it, the doc was hydrated from data without one, or _id was unset.

Source

Thrown at lib/model.js:791

/**
 * Returns a query object
 *
 * @api private
 * @method $__where
 * @memberOf Model
 * @instance
 */

Model.prototype.$__where = function _where(where) {
  where || (where = {});

  if (!where._id) {
    where._id = this._doc._id;
  }

  if (this._doc._id === void 0) {
    throw new MongooseError('No _id found on document!');
  }

  return where;
};

/**
 * Delete this document from the db. Returns a Query instance containing a `deleteOne` operation by this document's `_id`.
 *
 * #### Example:
 *
 *     await product.deleteOne();
 *     await Product.findById(product._id); // null
 *
 * Since `deleteOne()` returns a Query, the `deleteOne()` will **not** execute unless you use either `await`, `.then()`, `.catch()`, or [`.exec()`](https://mongoosejs.com/docs/api/query.html#Query.prototype.exec())
 *
 * #### Example:
 *
 *     product.deleteOne(); // Doesn't do anything

View on GitHub (pinned to 49cdab0136)

Solutions

  1. Delete by explicit filter on a unique natural key instead: Model.deleteOne({ slug: doc.slug })
  2. Hydrate documents from the database (with _id) before calling doc.deleteOne()
  3. Ensure the schema generates or requires _id so every loaded doc carries one

Example fix

// before
const doc = new TempModel({ jobId }); // schema has _id: false
await doc.deleteOne(); // throws: No _id found on document!

// after
await TempModel.deleteOne({ jobId });
Defensive patterns

Strategy: validation

Validate before calling

// Only attempt document deletion when an _id is present
async function deleteDoc(doc) {
  if (doc._id == null) {
    return doc.constructor.deleteOne({ jobId: doc.jobId }); // unique natural key
  }
  return doc.deleteOne();
}

Type guard

const hasDocumentId = (doc) => doc?._id !== undefined && doc?._id !== null;

Try / catch

try {
  await doc.deleteOne();
} catch (err) {
  if (err instanceof mongoose.MongooseError && /No _id found/.test(err.message)) {
    // fall back to Model.deleteOne with a unique filter
  } else throw err;
}

Prevention

When it happens

Trigger: doc.deleteOne() where doc was created as new Model({ name: 'x' }) under a schema with _id: false (or a String _id never assigned), or hydrated/cloned from a cached object that had no _id, or doc._id was deleted before the call.

Common situations: Reusing _id: false schemas for top-level docs; deserializing session/cache objects back into documents; test fixtures omitting _id; deleting a doc whose save earlier failed with 'document must have an _id before saving'.

Related errors


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