mongodb/node-mongodb-native · error · MongoTransactionError
Cannot call commitTransaction after calling abortTransaction
Error message
Cannot call commitTransaction after calling abortTransaction
What it means
`commitTransaction` throws MongoTransactionError when the transaction state is `TRANSACTION_ABORTED` — once a transaction has been aborted it cannot be committed. The abort is terminal for that transaction attempt.
Solutions
- Use a single owner for the transaction lifecycle; let one place commit or abort.
- Switch to `withTransaction` which never reaches this state.
- After aborting, decide explicitly whether to start a new transaction rather than committing the aborted one.
Example fix
// before
try {
session.startTransaction();
await collection.insertOne(doc, { session });
} catch (err) {
await session.abortTransaction();
} finally {
await session.commitTransaction(); // throws
}
// after
try {
session.startTransaction();
await collection.insertOne(doc, { session });
await session.commitTransaction();
} catch (err) {
await session.abortTransaction();
throw err;
} Defensive patterns
Strategy: validation
Validate before calling
// Decide abort-or-commit in exactly one place; never commit after abort.
function cleanup(session, { shouldCommit }) {
if (shouldCommit && session.inTransaction()) return session.commitTransaction();
if (session.inTransaction()) return session.abortTransaction();
} Prevention
- Single-owner the transaction lifecycle.
- Switch to `withTransaction`.
- After aborting, start a new transaction if needed instead of committing the aborted one.
When it happens
Trigger: `session.startTransaction(); ... await session.abortTransaction(); await session.commitTransaction();` — usually an error-handling block that aborts then a finally block that also tries to commit.
Common situations: Two try/catch layers each doing transaction cleanup; a generic cleanup that always commits in finally clashing with an inner catch that aborts; refactor that introduced a duplicate commit path.
Related errors
- Cannot call abortTransaction after calling commitTransaction
- Cannot call abortTransaction twice
- No transaction started
- Transaction already in progress
- 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/5c6c77358667c37c.
Report an issue: GitHub.
Appendix: source
Thrown at src/sessions.ts:444
*
* @param options - Optional options, can be used to override `defaultTimeoutMS`.
*/
async commitTransaction(options?: { timeoutMS?: number }): Promise<void> {
if (this.transaction.state === TxnState.NO_TRANSACTION) {
throw new MongoTransactionError('No transaction started');
}
if (
this.transaction.state === TxnState.STARTING_TRANSACTION ||
this.transaction.state === TxnState.TRANSACTION_COMMITTED_EMPTY
) {
// the transaction was never started, we can safely exit here
this.transaction.transition(TxnState.TRANSACTION_COMMITTED_EMPTY);
return;
}
if (this.transaction.state === TxnState.TRANSACTION_ABORTED) {
throw new MongoTransactionError(
'Cannot call commitTransaction after calling abortTransaction'
);
}
const command: {
commitTransaction: 1;
writeConcern?: WriteConcernSettings;
recoveryToken?: Document;
maxTimeMS?: number;
} = { commitTransaction: 1 };
const timeoutMS =
typeof options?.timeoutMS === 'number'
? options.timeoutMS
: typeof this.timeoutMS === 'number'
? this.timeoutMS
: null;
View on GitHub (pinned to dce7939f86)