mongodb/node-mongodb-native · error · MongoInvalidArgumentError
input cluster time "clusterTime" property must be a valid…
Error message
input cluster time "clusterTime" property must be a valid BSON Timestamp
What it means
`advanceClusterTime` requires the document's `clusterTime` field to be a BSON Timestamp (`_bsontype === 'Timestamp'`). A missing field or any other type triggers MongoInvalidArgumentError. Server `$clusterTime` documents always carry a Timestamp here; the check fails when the document was rebuilt from JSON/plain objects.
Solutions
- Transport cluster times via BSON serialisation, or rehydrate with `new Timestamp({ t: ct.clusterTime.high_, i: ct.clusterTime.low_ })` if you must cross JSON.
- Forward the whole `$clusterTime` sub-document straight from the server response without modification.
- Guard callers: `if (ct.clusterTime?._bsontype === 'Timestamp') session.advanceClusterTime(ct)`.
Example fix
// before
session.advanceClusterTime({ clusterTime: { t: 1, i: 1 }, signature: {...} });
// after
import { Timestamp } from 'mongodb';
session.advanceClusterTime({
clusterTime: new Timestamp({ t: 1, i: 1 }),
signature: { hash: ..., keyId: ... }
}); Defensive patterns
Strategy: type-guard
Validate before calling
import { Timestamp } from 'mongodb';
function safeAdvance(session, ct) {
if (ct?.clusterTime?._bsontype === 'Timestamp') {
session.advanceClusterTime(ct);
}
} Type guard
function isValidClusterTime(v) {
return v != null && typeof v === 'object' &&
v.clusterTime?._bsontype === 'Timestamp';
} Prevention
- Never round-trip cluster time through JSON; BSON-encode it.
- Rehydrate Timestamp fields explicitly if you must reconstruct.
- Forward the server's `$clusterTime` unmodified.
When it happens
Trigger: Forwarding a cluster time whose `clusterTime` was serialised to a plain object/number; manually constructing a cluster time doc without `new Timestamp(...)`; partially destructuring a server response.
Common situations: Multi-thread/process cluster-time sync over JSON transport (which strips BSON types); test fixtures that hand-build cluster time; reflection that loses prototype info.
Related errors
- input cluster time must be an object
- input cluster time must have a valid "signature" property…
- Cannot call abortTransaction after calling commitTransaction
- Cannot call abortTransaction twice
- Cannot call commitTransaction after calling abortTransaction
AI-assisted analysis of mongodb/node-mongodb-native@dce7939f86 (2026-08-11).
Data as JSON: /api/errors/eed770f157d78006.
Report an issue: GitHub.
Appendix: source
Thrown at src/sessions.ts:325
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'
);
}
_advanceClusterTime(this, clusterTime);
}
View on GitHub (pinned to dce7939f86)