mongodb/node-mongodb-native · error · MongoInvalidArgumentError
Document must be a valid JavaScript object
Error message
Document must be a valid JavaScript object
What it means
Thrown by makeUpdateStatement() (src/operations/update.ts:270) when the update argument is null or not an object/array. The driver validates the 'u' field of the wire-protocol update statement; it must be either an update document with operators (e.g. $set) or an aggregation pipeline array (for update with pipeline). Surfaces as MongoInvalidArgumentError synchronously.
Solutions
- Provide a valid update document (with operators like $set) or an aggregation pipeline array as the second argument.
- Verify the variable holding the update document is defined before calling the method.
- Double-check the argument order against the method signature.
Example fix
// before
collection.updateOne({ a: 1 }, maybeUpdate);
// after
const update = maybeUpdate ?? { $set: { updated: true } };
collection.updateOne({ a: 1 }, update); Defensive patterns
Strategy: validation
Validate before calling
function assertUpdate(update) {
if (update == null || (typeof update !== 'object' && typeof update !== 'object')) {
throw new TypeError('update must be an object or array');
}
}
assertUpdate(myUpdate);
collection.updateOne({}, myUpdate); Type guard
function isUpdateDoc(v): v is Record<string, unknown> | unknown[] {
return v != null && typeof v === 'object';
} Try / catch
try {
await collection.updateOne(filter, update);
} catch (e) {
if (e instanceof MongoInvalidArgumentError && /Document must be/.test(e.message)) {
// surface validation error
}
throw e;
} Prevention
- Always pass an explicit update document; never reuse a variable that could be undefined.
- Use TypeScript types (Document | Document[]) for update arguments.
- Unit-test the argument order of findOneAndUpdate calls.
When it happens
Trigger: Calling collection.updateOne({a:1}, null), collection.updateOne({a:1}, 'foo'), or collection.findOneAndUpdate(filter, undefined). Also from bulkWrite with a statement whose update field is not an object.
Common situations: Forgetting the update document, passing a JS expression that evaluated to undefined, or confusing the argument order of findOneAndUpdate(filter, update, options).
Related errors
- Selector must be a valid JavaScript object
- Update operations require that all atomic operators have…
- Argument "update" must be an object
- Invalid read preference mode
- Invalid read preference
AI-assisted analysis of mongodb/node-mongodb-native@dce7939f86 (2026-08-11).
Data as JSON: /api/errors/d5de58c55ba9e53a.
Report an issue: GitHub.
Appendix: source
Thrown at src/operations/update.ts:270
upsertedId:
Array.isArray(res.upserted) && res.upserted.length > 0 ? res.upserted[0]._id : null,
upsertedCount: Array.isArray(res.upserted) && res.upserted.length ? res.upserted.length : 0,
matchedCount: Array.isArray(res.upserted) && res.upserted.length > 0 ? 0 : res.n
};
}
}
export function makeUpdateStatement(
filter: Document,
update: Document | Document[],
options: UpdateOptions & { multi?: boolean } & { sort?: Sort }
): UpdateStatement {
if (filter == null || typeof filter !== 'object') {
throw new MongoInvalidArgumentError('Selector must be a valid JavaScript object');
}
if (update == null || typeof update !== 'object') {
throw new MongoInvalidArgumentError('Document must be a valid JavaScript object');
}
const op: UpdateStatement = { q: filter, u: update };
if (typeof options.upsert === 'boolean') {
op.upsert = options.upsert;
}
if (options.multi) {
op.multi = options.multi;
}
if (options.hint) {
op.hint = options.hint;
}
if (options.arrayFilters) {
op.arrayFilters = options.arrayFilters;
}View on GitHub (pinned to dce7939f86)