mongodb/node-mongodb-native · error · MongoRuntimeError

ClientSession cannot be serialized to BSON.

Error message

ClientSession cannot be serialized to BSON.

What it means

ClientSession defines a toBSON() method that unconditionally throws a MongoRuntimeError. This is a deliberate guard: BSON serialization invokes toBSON() on objects that define it, so if a ClientSession is embedded as a field value in a document being inserted/updated, BSON would otherwise silently serialize it (or fail opaquely). The guard makes the misuse loud and immediate.

Source

Thrown at src/sessions.ts:676

          }
          // we do not retry the retry
        }
      }

      // The spec indicates that if the operation times out or fails with a non-retryable error, we should ignore all errors on `abortTransaction`
    } finally {
      this.transaction.transition(TxnState.TRANSACTION_ABORTED);
      if (this.loadBalanced) {
        maybeClearPinnedConnection(this, { force: false });
      }
    }
  }

  /**
   * This is here to ensure that ClientSession is never serialized to BSON.
   */
  toBSON(): never {
    throw new MongoRuntimeError('ClientSession cannot be serialized to BSON.');
  }

  /**
   * Starts a transaction and runs a provided function, ensuring the commitTransaction is always attempted when all operations run in the function have completed.
   *
   * **IMPORTANT:** This method requires the function passed in to return a Promise. That promise must be made by `await`-ing all operations in such a way that rejections are propagated to the returned promise.
   *
   * **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.
   *
   * **IMPORTANT:** When running an operation inside a `withTransaction` callback, if it is not
   * provided the explicit session in its options, it will not be part of the transaction and it will not respect timeoutMS.
   *
   *
   * @remarks
   * - If all operations successfully complete and the `commitTransaction` operation is successful, then the provided function will return the result of the provided function.
   * - If the transaction is unable to complete or an error is thrown from within the provided function, then the provided function will throw an error.

View on GitHub (pinned to 3366c21a63)

Solutions

  1. Move the session out of the document and into the options argument: coll.insertOne(doc, { session }).
  2. Audit the document body for stray session references before writing; strip keys that are ClientSession instances.
  3. Use a type guard to assert no field of the document is a ClientSession before insert.

Example fix

// before
const session = client.startSession();
await coll.insertOne({ name: 'x', session }, { session }); // 'session' key in doc throws

// after
const session = client.startSession();
await coll.insertOne({ name: 'x' }, { session });
Defensive patterns

Strategy: type-guard

Validate before calling

import { ClientSession } from 'mongodb';
function hasSessionValue(doc: unknown): boolean {
  if (doc == null || typeof doc !== 'object') return false;
  return Object.values(doc).some(v => v instanceof ClientSession);
}
if (!hasSessionValue(myDoc)) {
  await coll.insertOne(myDoc, { session });
}

Type guard

import { ClientSession } from 'mongodb';
function isClientSession(v: unknown): v is ClientSession {
  return v instanceof ClientSession;
}

Try / catch

try {
  await coll.insertOne(doc, { session });
} catch (e) {
  if (e instanceof MongoRuntimeError && /cannot be serialized to BSON/.test(e.message)) {
    // a ClientSession leaked into the doc body; strip session-shaped values and retry
  } else throw e;
}

Prevention

When it happens

Trigger: Inserting/updating a document that contains a ClientSession reference as a property value, e.g. { user: 'x', session } passed to insertOne instead of { session } as the options bag. Also spreading a session into a doc by accident, or storing it on an object that is later serialized.

Common situations: Passing the wrong argument shape to insertOne/updateOne (session mixed into the document); destructuring session into a payload object; middleware that attaches the session to req and later persists req.

Related errors


AI-assisted analysis of mongodb/node-mongodb-native@3366c21a63 (2026-08-04). Data as JSON: /data/errors/000ccfdf1a07412e.json. Report an issue: GitHub.