{"id":"43a7a647d06594ae","repo":"mongodb/node-mongodb-native","slug":"no-transaction-started","errorCode":null,"errorMessage":"No transaction started","messagePattern":"No transaction started","errorType":"exception","errorClass":"MongoTransactionError","httpStatus":null,"severity":"error","filePath":"src/sessions.ts","lineNumber":431,"sourceCode":"        this.clientOptions?.writeConcern,\n      readPreference:\n        options?.readPreference ??\n        this.defaultTransactionOptions.readPreference ??\n        this.clientOptions?.readPreference,\n      maxCommitTimeMS: options?.maxCommitTimeMS ?? this.defaultTransactionOptions.maxCommitTimeMS\n    });\n\n    this.transaction.transition(TxnState.STARTING_TRANSACTION);\n  }\n\n  /**\n   * Commits the currently active transaction in this session.\n   *\n   * @param options - Optional options, can be used to override `defaultTimeoutMS`.\n   */\n  async commitTransaction(options?: { timeoutMS?: number }): Promise<void> {\n    if (this.transaction.state === TxnState.NO_TRANSACTION) {\n      throw new MongoTransactionError('No transaction started');\n    }\n\n    if (\n      this.transaction.state === TxnState.STARTING_TRANSACTION ||\n      this.transaction.state === TxnState.TRANSACTION_COMMITTED_EMPTY\n    ) {\n      // the transaction was never started, we can safely exit here\n      this.transaction.transition(TxnState.TRANSACTION_COMMITTED_EMPTY);\n      return;\n    }\n\n    if (this.transaction.state === TxnState.TRANSACTION_ABORTED) {\n      throw new MongoTransactionError(\n        'Cannot call commitTransaction after calling abortTransaction'\n      );\n    }\n\n    const command: {","sourceCodeStart":413,"sourceCodeEnd":449,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/3366c21a6311e02f1be91da982f9b93d3cce99a0/src/sessions.ts#L413-L449","documentation":"Thrown by ClientSession.commitTransaction() when the transaction state is NO_TRANSACTION, i.e. startTransaction was never called (or the prior transaction was fully cleared). The driver refuses to send a commit command with no transaction context. It is a MongoTransactionError.","triggerScenarios":"Calling commitTransaction() on a fresh session that never started a transaction; calling commit again after a prior commit/abort cycle reset state to NO_TRANSACTION.","commonSituations":"A finally block that always calls commitTransaction regardless of whether start ran; conditional start paths where the start branch was skipped but commit runs unconditionally; using the same session across sequential transactions without restarting.","solutions":["Gate commit on active state: if (session.inTransaction()) await session.commitTransaction().","Use withTransaction() to let the driver own commit timing.","Restructure so commitTransaction is only on the success path of a started transaction.","After committing/aborting, start a new transaction before committing again."],"exampleFix":"// before\ntry {\n  if (needsWrite) session.startTransaction();\n  await coll.insertOne(doc, { session });\n} finally {\n  await session.commitTransaction(); // throws when needsWrite was false\n}\n\n// after\ntry {\n  if (needsWrite) {\n    session.startTransaction();\n    await coll.insertOne(doc, { session });\n    await session.commitTransaction();\n  }\n} catch (e) {\n  if (session.inTransaction()) await session.abortTransaction();\n  throw e;\n}","handlingStrategy":"validation","validationCode":"if (session.inTransaction()) {\n  await session.commitTransaction();\n}","typeGuard":"function hasActiveTransaction(session: ClientSession): boolean {\n  return session.inTransaction();\n}","tryCatchPattern":"try {\n  await session.commitTransaction();\n} catch (e) {\n  if (e instanceof MongoTransactionError && /No transaction started/.test(e.message)) {\n    // no-op; nothing to commit\n  } else throw e;\n}","preventionTips":["Gate commitTransaction() behind session.inTransaction().","Avoid finally blocks that commit unconditionally.","Use withTransaction() so commit only runs after a successful callback."],"tags":["sessions","transactions","state-machine","control-flow"],"analyzedSha":"3366c21a6311e02f1be91da982f9b93d3cce99a0","analyzedAt":"2026-08-04T13:40:15.335Z","schemaVersion":2}