mongodb/node-mongodb-native · error · MongoTransactionError
Transaction already in progress
Error message
Transaction already in progress
What it means
`startTransaction` throws MongoTransactionError when `inTransaction()` is already true — a session hosts at most one transaction at a time. The check protects transaction state from being overwritten mid-flight.
Solutions
- Commit or abort before starting again: `await session.commitTransaction()` or `await session.abortTransaction()`.
- Prefer `session.withTransaction(async (s) => { ... })` — it manages start/commit/abort/retry for you.
- Always pair start with a finally block: `try { session.startTransaction(); ... await session.commitTransaction(); } catch { await session.abortTransaction(); throw; }`.
Example fix
// before
session.startTransaction();
await collection.insertOne(doc, { session });
session.startTransaction(); // throws
// after
await session.withTransaction(async (s) => {
await collection.insertOne(doc, { session: s });
}); Defensive patterns
Strategy: validation
Validate before calling
function safeStart(session, opts) {
if (session.inTransaction()) {
throw new Error('transaction already in progress; commit or abort first');
}
session.startTransaction(opts);
} Type guard
function canStartTxn(session) {
return !session.inTransaction();
} Prevention
- Prefer `withTransaction` to avoid manual start/commit/abort ordering.
- Always pair `startTransaction` with commit/abort before starting again.
- Add an `if (session.inTransaction())` guard around manual starts.
When it happens
Trigger: `session.startTransaction(); ... session.startTransaction();` without an intervening commit or abort; control-flow bug where startTransaction is called in a loop body unconditionally.
Common situations: Refactoring a sequential flow into a loop and forgetting to commit/abort each iteration; calling withTransaction and also manually calling startTransaction inside the callback; error paths that skip abort.
Related errors
- Cannot call abortTransaction after calling commitTransaction
- Cannot call abortTransaction twice
- Cannot call commitTransaction after calling abortTransaction
- No transaction started
- Function provided to `withTransaction` must return a Promise
AI-assisted analysis of mongodb/node-mongodb-native@dce7939f86 (2026-08-11).
Data as JSON: /api/errors/af599726e0497d78.
Report an issue: GitHub.
Appendix: source
Thrown at src/sessions.ts:394
}
/**
* Starts a new transaction with the given options.
*
* @remarks
* **IMPORTANT**: Running operations in parallel is not supported during a transaction. The use of `Promise.all`,
* `Promise.allSettled`, `Promise.race`, etc to parallelize operations inside a transaction is
* undefined behaviour.
*
* @param options - Options for the transaction
*/
startTransaction(options?: TransactionOptions): void {
if (this.snapshotEnabled) {
throw new MongoCompatibilityError('Transactions are not supported in snapshot sessions');
}
if (this.inTransaction()) {
throw new MongoTransactionError('Transaction already in progress');
}
if (this.isPinned && this.transaction.isCommitted) {
this.unpin();
}
this.commitAttempted = false;
// increment txnNumber
this.incrementTransactionNumber();
// create transaction state
this.transaction = new Transaction({
readConcern:
options?.readConcern ??
this.defaultTransactionOptions.readConcern ??
this.clientOptions?.readConcern,
writeConcern:
options?.writeConcern ??
this.defaultTransactionOptions.writeConcern ??View on GitHub (pinned to dce7939f86)