{"id":"2a1e8451cd487c9e","repo":"mongodb/node-mongodb-native","slug":"input-cluster-time-must-be-an-object","errorCode":null,"errorMessage":"input cluster time must be an object","messagePattern":"input cluster time must be an object","errorType":"exception","errorClass":"MongoInvalidArgumentError","httpStatus":null,"severity":"error","filePath":"src/sessions.ts","lineNumber":322,"sourceCode":"  advanceOperationTime(operationTime: Timestamp): void {\n    if (this.operationTime == null) {\n      this.operationTime = operationTime;\n      return;\n    }\n\n    if (operationTime.greaterThan(this.operationTime)) {\n      this.operationTime = operationTime;\n    }\n  }\n\n  /**\n   * Advances the clusterTime for a ClientSession to the provided clusterTime of another ClientSession\n   *\n   * @param clusterTime - the $clusterTime returned by the server from another session in the form of a document containing the `BSON.Timestamp` clusterTime and signature\n   */\n  advanceClusterTime(clusterTime: ClusterTime): void {\n    if (!clusterTime || typeof clusterTime !== 'object') {\n      throw new MongoInvalidArgumentError('input cluster time must be an object');\n    }\n    if (!clusterTime.clusterTime || clusterTime.clusterTime._bsontype !== 'Timestamp') {\n      throw new MongoInvalidArgumentError(\n        'input cluster time \"clusterTime\" property must be a valid BSON Timestamp'\n      );\n    }\n    if (\n      !clusterTime.signature ||\n      clusterTime.signature.hash?._bsontype !== 'Binary' ||\n      (typeof clusterTime.signature.keyId !== 'bigint' &&\n        typeof clusterTime.signature.keyId !== 'number' &&\n        clusterTime.signature.keyId?._bsontype !== 'Long') // apparently we decode the key to number?\n    ) {\n      throw new MongoInvalidArgumentError(\n        'input cluster time must have a valid \"signature\" property with BSON Binary hash and BSON Long keyId'\n      );\n    }\n","sourceCodeStart":304,"sourceCodeEnd":340,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/3366c21a6311e02f1be91da982f9b93d3cce99a0/src/sessions.ts#L304-L340","documentation":"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.","triggerScenarios":"Calling `session.advanceClusterTime('123')`, passing a number/boolean, or forwarding a malformed (non-object) cluster time from another session's serialization.","commonSituations":"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.","solutions":["Pass the full `$clusterTime` document object returned by the server (e.g. `commandResult.$clusterTime`).","If forwarding between clients, use `client.advanceClusterTime(otherSession.clusterTime)` which yields a proper object.","Validate the value is an object before calling."],"exampleFix":"// before\nsession.advanceClusterTime(JSON.stringify(doc.$clusterTime));\n// after\nsession.advanceClusterTime(doc.$clusterTime);","handlingStrategy":"type-guard","validationCode":"function advanceClusterTimeSafe(session, clusterTime) {\n  if (!clusterTime || typeof clusterTime !== 'object') {\n    throw new TypeError('clusterTime must be an object');\n  }\n  return session.advanceClusterTime(clusterTime);\n}","typeGuard":"function isClusterTimeObject(ct) {\n  return ct != null && typeof ct === 'object' && !Array.isArray(ct);\n}","tryCatchPattern":null,"preventionTips":["Forward the original server $clusterTime document verbatim.","Avoid JSON round-tripping cluster times.","Validate the argument type before calling advanceClusterTime."],"tags":["sessions","validation"],"analyzedSha":"3366c21a6311e02f1be91da982f9b93d3cce99a0","analyzedAt":"2026-08-04T13:40:15.335Z","schemaVersion":2}