mongodb/node-mongodb-native · error · MongoInvalidArgumentError

input cluster time must be an object

Error message

input cluster time must be an object

What it means

Thrown by `ClientSession.advanceClusterTime` when the argument is not an object (sessions.ts:321). `advanceClusterTime` gossips the `$clusterTime` returned by the server across sessions/clients; it expects a document shaped like `{ clusterTime: Timestamp, signature: {...} }`. A primitive or null cannot be merged.

Source

Thrown at src/sessions.ts:322

  advanceOperationTime(operationTime: Timestamp): void {
    if (this.operationTime == null) {
      this.operationTime = operationTime;
      return;
    }

    if (operationTime.greaterThan(this.operationTime)) {
      this.operationTime = operationTime;
    }
  }

  /**
   * Advances the clusterTime for a ClientSession to the provided clusterTime of another ClientSession
   *
   * @param clusterTime - the $clusterTime returned by the server from another session in the form of a document containing the `BSON.Timestamp` clusterTime and signature
   */
  advanceClusterTime(clusterTime: ClusterTime): void {
    if (!clusterTime || typeof clusterTime !== 'object') {
      throw new MongoInvalidArgumentError('input cluster time must be an object');
    }
    if (!clusterTime.clusterTime || clusterTime.clusterTime._bsontype !== 'Timestamp') {
      throw new MongoInvalidArgumentError(
        'input cluster time "clusterTime" property must be a valid BSON Timestamp'
      );
    }
    if (
      !clusterTime.signature ||
      clusterTime.signature.hash?._bsontype !== 'Binary' ||
      (typeof clusterTime.signature.keyId !== 'bigint' &&
        typeof clusterTime.signature.keyId !== 'number' &&
        clusterTime.signature.keyId?._bsontype !== 'Long') // apparently we decode the key to number?
    ) {
      throw new MongoInvalidArgumentError(
        'input cluster time must have a valid "signature" property with BSON Binary hash and BSON Long keyId'
      );
    }

View on GitHub (pinned to 3366c21a63)

Solutions

  1. Pass the full `$clusterTime` document object returned by the server (e.g. `commandResult.$clusterTime`).
  2. If forwarding between clients, use `client.advanceClusterTime(otherSession.clusterTime)` which yields a proper object.
  3. Validate the value is an object before calling.

Example fix

// before
session.advanceClusterTime(JSON.stringify(doc.$clusterTime));
// after
session.advanceClusterTime(doc.$clusterTime);
Defensive patterns

Strategy: type-guard

Validate before calling

function advanceClusterTimeSafe(session, clusterTime) {
  if (!clusterTime || typeof clusterTime !== 'object') {
    throw new TypeError('clusterTime must be an object');
  }
  return session.advanceClusterTime(clusterTime);
}

Type guard

function isClusterTimeObject(ct) {
  return ct != null && typeof ct === 'object' && !Array.isArray(ct);
}

Prevention

When it happens

Trigger: Calling `session.advanceClusterTime('123')`, passing a number/boolean, or forwarding a malformed (non-object) cluster time from another session's serialization.

Common situations: Copying a cluster time that was JSON-stringified then not parsed; passing `clusterTime` from a response field that was undefined; building cluster-time docs manually with wrong types.

Related errors


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