Mongoose VersionError: No matching document found for id

Thông báo lỗi này từ Mongoose:

VersionError: No matching document found for id ... version ...

🧠 Giải thích:

Mongoose bật "Optimistic Concurrency Control" (OCC) theo mặc định nếu:

  • Bạn dùng .save() trên một document có __v (version key).
  • Giữa lúc bạn đang xử lý, document đó bị người khác update__v bị thay đổi.
  • Khi bạn gọi .save(), Mongoose kiểm tra __v. Nếu không khớp → báo lỗi như trên.

🔍 Ví dụ cụ thể:

const doc1 = await MyModel.findById(id);
const doc2 = await MyModel.findById(id);

doc1.name = 'Alice';
await doc1.save(); // OK, __v tăng từ 5 → 6

doc2.name = 'Bob';
await doc2.save(); // ❌ lỗi: version mismatch (__v = 5 expected, nhưng giờ là 6)

✅ Cách khắc phục


1. Dùng updateOne() hoặc findByIdAndUpdate() với atomic operator

✅ Không dùng .save() thì Mongoose không check __v
await MyModel.updateOne(
  { _id: id },
  { $set: { name: 'Bob' } }
);

2. Retry lại khi gặp lỗi version

Bạn có thể bắt lỗi và load lại document:

try {
  await doc.save();
} catch (err) {
  if (err.name === 'VersionError') {
    const latestDoc = await MyModel.findById(doc._id);
    // xử lý lại và lưu lại
  }
}

3. Tắt OCC (Không khuyến khích)

const schema = new mongoose.Schema({ ... }, { optimisticConcurrency: false });
⚠️ Nếu bạn tắt OCC thì phải tự xử lý tránh conflict.

4. Dùng $inc, $set, $push qua updateOne() nếu có nhiều API gọi liên tục

Với API "gọi liên tục", .save() dễ gây xung đột → chuyển sang dùng updateOne() là tốt nhất.