Automattic/mongoose · error · MongooseError
Cannot call `create()` with a session and multiple documents
Error message
Cannot call `create()` with a session and multiple documents unless `ordered: true` is set
What it means
Model.create() saves multiple documents in parallel with Promise.all by default. When a session is supplied, parallel saves can interleave on the same session (typically inside a transaction), so Mongoose requires ordered: true, which switches to a serial for-loop over $save() calls. If options.session is set, options.ordered is falsy, and more than one document is being created, this MongooseError is thrown (as a rejected promise, since create() is async).
Source
Thrown at lib/model.js:2746
!this.schema.path('session')) {
// Probably means the user is running into the common mistake of trying
// to use a spread to specify options, see gh-7535
utils.warn('WARNING: to pass a `session` to `Model.create()` in ' +
'Mongoose, you **must** pass an array as the first argument. See: ' +
'https://mongoosejs.com/docs/api/model.html#Model.create()');
}
}
if (args.length === 0) {
return Array.isArray(doc) ? [] : null;
}
let res = [];
const immediateError = typeof options.aggregateErrors === 'boolean' ? !options.aggregateErrors : true;
delete options.aggregateErrors; // dont pass on the option to "$save"
if (options.session && !options.ordered && args.length > 1) {
throw new MongooseError('Cannot call `create()` with a session and multiple documents unless `ordered: true` is set');
}
if (!Array.isArray(doc) && args.length === 1) {
let toSave = doc;
const Model = this.discriminators && doc[discriminatorKey] != null ?
this.discriminators[doc[discriminatorKey]] || getDiscriminatorByValue(this.discriminators, doc[discriminatorKey]) :
this;
if (Model == null) {
throw new MongooseError(`Discriminator "${doc[discriminatorKey]}" not ` +
`found for model "${this.modelName}"`);
}
if (!(toSave instanceof Model)) {
toSave = new Model(toSave);
}
await toSave.$save(options);View on GitHub (pinned to 49cdab0136)
Solutions
- Add ordered: true: await Model.create([d1, d2], { session, ordered: true })
- Or create documents one at a time in the session: for (const d of docs) await Model.create(d, { session })
- Or use insertMany(docs, { session }) when middleware/hooks are not needed (insertMany is ordered by default)
- Only pass a session when one is actually required; plain create() calls without a session are unaffected
Example fix
// before
await session.withTransaction(async () => {
await User.create([u1, u2], { session }); // throws
});
// after
await session.withTransaction(async () => {
await User.create([u1, u2], { session, ordered: true });
}); Defensive patterns
Strategy: validation
Validate before calling
function createWithSession(Model, docs, session) {
const opts = { session, ordered: true };
if (opts.session && !opts.ordered && docs.length > 1) {
throw new Error('pass ordered: true when using a session with multiple docs');
}
return Model.create(docs, opts);
} Try / catch
try {
await Model.create(docs, { session, ordered: true });
} catch (err) {
if (/unless `ordered: true` is set/.test(err.message)) {
await Model.create(docs, { session, ordered: true }); // retry with ordered
} else throw err;
} Prevention
- Treat { session } as implying ordered: true in your create helpers
- Keep transaction code paths in one wrapper so session handling is uniform
- Prefer insertMany(docs, { session }) when hooks are unnecessary
When it happens
Trigger: await Model.create([d1, d2], { session }) inside a transaction (or with any session) without ordered: true. Also Model.create(d1, d2, { session }) spread form with a session in options.
Common situations: Wrapping multi-document creation in withTransaction(); adding { session } to existing bulk create calls during a refactor to transactions; passing a session from caller middleware to a generic create helper.
Related errors
- Invalid arguments
- Invalid sort() argument. Must be a string or object.
- Cannot set a document's session to a session that has ended.
- Must provide `autoEncryption` when connecting with encrypted
- Model.create() no longer accepts a callback
AI-assisted analysis of Automattic/mongoose@49cdab0136 (2026-08-21).
Data as JSON: /api/errors/d5746d183a20d3e0.
Report an issue: GitHub.