Skip to content

Commit bfe8919

Browse files
authored
Merge pull request #15743 from Mario5T/master
Added a new FAQ entry right before the final “Something to add?” sect…
2 parents dfa12ca + 05882c0 commit bfe8919

File tree

2 files changed

+47
-2
lines changed

2 files changed

+47
-2
lines changed

docs/faq.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,51 @@ await query.clone(); // Works
430430
Note: Mongoose v7+ no longer supports callbacks. If you're seeing duplicate queries in older code,
431431
it may be due to mixing callbacks and promises, which is no longer possible in current versions.
432432

433+
<hr id="divergent-array-error" />
434+
435+
<a class="anchor" href="#divergent-array-error">**Q**</a>. What does `DivergentArrayError` mean and how do I fix it?
436+
437+
**A**. Mongoose throws `DivergentArrayError` when you call `document.save()` to update an array that was only partially loaded, for example:
438+
439+
* the array was selected using an `$elemMatch` projection
440+
* the array was populated using `populate()` with `skip`, `limit`, query conditions, or options that exclude `_id`
441+
* the save would result in MongoDB performing a `$set` or `$pop` of the entire array
442+
443+
Because only part of the array is in memory, Mongoose can't safely reconstruct the full array to send back to MongoDB without risking data loss, so it throws `DivergentArrayError` instead.
444+
445+
For example:
446+
447+
```javascript
448+
const doc = await BlogPost.findOne(
449+
{ _id },
450+
{ comments: { $elemMatch: { flagged: true } } }
451+
);
452+
453+
doc.comments[0].text = 'Updated';
454+
await doc.save();
455+
```
456+
457+
To fix this error, either:
458+
459+
(1) Load the full array before modifying and saving:
460+
461+
```javascript
462+
const doc = await BlogPost.findById(_id);
463+
doc.comments.id(commentId).text = 'Updated';
464+
await doc.save();
465+
```
466+
467+
(2) Or use `updateOne()` / `updateMany()` with positional operators or `arrayFilters` so MongoDB can update the array atomically without requiring the full array on the document:
468+
469+
```javascript
470+
await BlogPost.updateOne(
471+
{ _id, 'comments._id': commentId },
472+
{ $set: { 'comments.$.text': 'Updated' } }
473+
);
474+
```
475+
476+
The same guidance applies if you populated an array with `skip`, `limit`, query conditions, or excluded `_id`: avoid calling `save()` to update that partially loaded array; instead, re-query without those options or use an update operation as shown above.
477+
433478
<hr id="add_something" />
434479

435480
**Something to add?**

lib/error/divergentArray.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ class DivergentArrayError extends MongooseError {
2323
+ 'the entire array is not supported. The following '
2424
+ 'path(s) would have been modified unsafely:\n'
2525
+ ' ' + paths.join('\n ') + '\n'
26-
+ 'Use Model.updateOne() to update these arrays instead.';
27-
// TODO write up a docs page (FAQ) and link to it
26+
+ 'Use Model.updateOne() to update these arrays instead. '
27+
+ 'See https://mongoosejs.com/docs/faq.html#divergent-array-error for more information.';
2828
super(msg);
2929
}
3030
}

0 commit comments

Comments
 (0)