{"id":"361822ad2ec3f1e9","repo":"mongodb/node-mongodb-native","slug":"transactions-do-not-support-unacknowledged-write-c","errorCode":null,"errorMessage":"Transactions do not support unacknowledged write concern","messagePattern":"Transactions do not support unacknowledged write concern","errorType":"exception","errorClass":"MongoTransactionError","httpStatus":null,"severity":"error","filePath":"src/transactions.ts","lineNumber":93,"sourceCode":"/**\n * @internal\n */\nexport class Transaction {\n  state: TxnState;\n  options: TransactionOptions;\n  _pinnedServer?: Server;\n  _recoveryToken?: Document;\n\n  /** Create a transaction */\n  constructor(options?: TransactionOptions) {\n    options = options ?? {};\n    this.state = TxnState.NO_TRANSACTION;\n    this.options = {};\n\n    const writeConcern = WriteConcern.fromOptions(options);\n    if (writeConcern) {\n      if (writeConcern.w === 0) {\n        throw new MongoTransactionError('Transactions do not support unacknowledged write concern');\n      }\n\n      this.options.writeConcern = writeConcern;\n    }\n\n    if (options.readConcern) {\n      this.options.readConcern = ReadConcern.fromOptions(options);\n    }\n\n    if (options.readPreference) {\n      this.options.readPreference = ReadPreference.fromOptions(options);\n    }\n\n    if (options.maxCommitTimeMS) {\n      this.options.maxTimeMS = options.maxCommitTimeMS;\n    }\n\n    // TODO: This isn't technically necessary","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/3366c21a6311e02f1be91da982f9b93d3cce99a0/src/transactions.ts#L75-L111","documentation":"Thrown by the @internal Transaction constructor when the resolved write concern has w === 0 (unacknowledged). MongoDB transactions require acknowledged writes because commit/abort depend on the server's command response, so the driver rejects unacknowledged write concern at transaction start. It is a MongoTransactionError.","triggerScenarios":"Calling session.startTransaction({ writeConcern: { w: 0 } }), or inheriting a w:0 write concern from the client/defaultTransactionOptions and starting a transaction.","commonSituations":"Sharing a writeConcern configured for fire-and-forget inserts with transaction code; setting MongoClient writeConcern to { w: 0 } globally; copying options between code paths.","solutions":["Omit writeConcern from startTransaction options to let the driver use the default (acknowledged, majority on commit).","If specifying writeConcern, use w >= 1 or 'majority'.","Audit the client-level writeConcern and defaultTransactionOptions if the error appears without explicit transaction options."],"exampleFix":"// before\nawait session.withTransaction(\n  async (s) => { await coll.insertOne(doc, { session: s }); },\n  { writeConcern: { w: 0 } } // throws\n);\n\n// after\nawait session.withTransaction(\n  async (s) => { await coll.insertOne(doc, { session: s }); },\n  { writeConcern: { w: 'majority' } }\n);","handlingStrategy":"validation","validationCode":"function isAcknowledged(wc: any): boolean {\n  return wc == null || wc.w === undefined || wc.w === 'majority' ||\n    (typeof wc.w === 'number' && wc.w >= 1);\n}\nif (isAcknowledged(txnOptions.writeConcern)) {\n  session.startTransaction(txnOptions);\n}","typeGuard":"function isAcknowledgedWriteConcern(wc: unknown): boolean {\n  if (wc == null) return true;\n  if (typeof wc === 'object') {\n    const w = (wc as any).w;\n    return w === undefined || w === 'majority' || (typeof w === 'number' && w >= 1);\n  }\n  return false;\n}","tryCatchPattern":"try {\n  session.startTransaction(options);\n} catch (e) {\n  if (e instanceof MongoTransactionError && /unacknowledged write concern/.test(e.message)) {\n    const { w: _, ...ack } = options.writeConcern ?? {};\n    session.startTransaction({ ...options, writeConcern: { ...ack, w: 'majority' } });\n  } else throw e;\n}","preventionTips":["Never set w:0 on a client/session used for transactions.","Validate writeConcern.w >= 1 before passing options to startTransaction/withTransaction.","Keep fire-and-forget insert paths on a separate client from transactional paths."],"tags":["transactions","write-concern","invalid-argument"],"analyzedSha":"3366c21a6311e02f1be91da982f9b93d3cce99a0","analyzedAt":"2026-08-04T13:40:15.335Z","schemaVersion":2}