npm / mongoose
mongoose
What changed in mongoose 8 to 9, from its official release notes, upgrade guides and advisories. Sources checked 2026-10-21.
1 breaking2 security2 performance1 behavior and defaults15 fixes and other
See which of these apply to your code, ranked, in your agent:
npx @unstale/cli initmongoose 916 changes
Security 2
Mongoose: Prototype pollution in mongoose update casting via __proto__-prefixed dotted path (Schema._getSchema/path getter)
Mongoose's Improper Sanitization of $nor in sanitizeFilter May Allow NoSQL Injection
Performance 2
Makes MergeType more efficiently handle MergeType<A, {}>.
Avoids applying saveSubdocs and sharding plugins to subdocuments.
Behavior and default changes 1
Int32 paths are now treated as number in schema types.
Fixes and other changes 11
Casts array filter values in bulkWrite().
Allows function messages for number min/max and string minlength validators.
Array filters continue to be cast after a path not in the schema.
Filters selecting a discriminator key with $eq or $in now use the embedded discriminator schema.
flattenDecimals is now applied when toObject() takes the shallow fast path.
Initializing nested document arrays no longer passes arrayPathIndex to subdocuments.
Operators under $not inside $elemMatch on primitive arrays are now cast.
Destroying query cursors now awaits driver cleanup.
Setting a path to a nested object now calls recursive toObject().
UpdateManyModel update typing is now aligned with UpdateQuery.
UpdateOneModel update typing is now aligned with UpdateQuery.
mongoose 85 changes
Breaking changes 1
Casting to Int32 or Double now rejects arrays.
Fixes and other changes 4
Cloning with a seen map now preserves circular arrays.
The schema is now passed through when casting a nested comparison.
pull() now removes dates by comparing their values in indexOf(), rather than relying on reference equality.
Query path collisions are avoided when excluding a subdocument that has a select: false child.