mongodb/node-mongodb-native · error · MongoInvalidArgumentError
Update operations require that all atomic operators have…
Error message
Update operations require that all atomic operators have defined values, but none were provided.
What it means
Thrown by hasAtomicOperators() when the ignoreUndefined option is set and every value in the update document is undefined. This guards against updateOne/updateMany calls where all operator fields (e.g. $set values) are undefined, which would produce a no-op or malformed command. Raised as MongoInvalidArgumentError.
Solutions
- Filter out undefined values before constructing the update document, and ensure at least one field has a defined value.
- If no fields are present to update, skip the update call entirely.
- Do not enable ignoreUndefined unless you also validate that the update document is non-empty.
Example fix
// before
const update = { $set: { name: body.name, age: body.age } }; // both undefined
collection.updateOne(filter, update, { ignoreUndefined: true });
// after
const setFields = {};
if (body.name !== undefined) setFields.name = body.name;
if (body.age !== undefined) setFields.age = body.age;
if (Object.keys(setFields).length) {
await collection.updateOne(filter, { $set: setFields }, { ignoreUndefined: true });
} Defensive patterns
Strategy: validation
Validate before calling
function buildSet(update: Record<string, unknown>): Record<string, unknown> | null {
const set: Record<string, unknown> = {};
for (const [k, v] of Object.entries(update)) if (v !== undefined) set[k] = v;
return Object.keys(set).length ? set : null;
}
const setFields = buildSet(req.body);
if (setFields) await collection.updateOne(filter, { $set: setFields }, { ignoreUndefined: true }); Type guard
function hasDefinedValues(doc: Record<string, unknown>): boolean {
return Object.values(doc).some(v => v !== undefined);
} Try / catch
try {
await collection.updateOne(filter, { $set: patch }, { ignoreUndefined: true });
} catch (e) {
if (e instanceof MongoInvalidArgumentError && /atomic operators have defined values/.test(e.message)) {
// no-op: nothing to update
} else throw e;
} Prevention
- Strip undefined values from update objects before calling updateOne/updateMany.
- Skip the update entirely when no fields have defined values.
- Only enable ignoreUndefined when you also pre-validate the update document.
When it happens
Trigger: Calling collection.updateOne(filter, { $set: { field: value } }, { ignoreUndefined: true }) where value resolves to undefined for all fields. Common when building update objects from optional request body fields that are all absent.
Common situations: API handlers that spread optional user-supplied fields into a $set object with ignoreUndefined enabled, and the incoming payload has none of the expected fields. The resulting update document has only undefined values, so the driver rejects it rather than sending an empty update.
Related errors
- Document must be a valid JavaScript object
- Selector must be a valid JavaScript object
- Argument "update" must be an object
- Invalid sort direction
- Invalid sort format: Sort must be a valid object
AI-assisted analysis of mongodb/node-mongodb-native@dce7939f86 (2026-08-11).
Data as JSON: /api/errors/ddbec88a31d46538.
Report an issue: GitHub.
Appendix: source
Thrown at src/utils.ts:481
return true;
}
}
return false;
}
const keys = Object.keys(doc);
// In this case we need to throw if all the atomic operators are undefined.
if (options?.ignoreUndefined) {
let allUndefined = true;
for (const key of keys) {
// eslint-disable-next-line no-restricted-syntax
if (doc[key] !== undefined) {
allUndefined = false;
break;
}
}
if (allUndefined) {
throw new MongoInvalidArgumentError(
'Update operations require that all atomic operators have defined values, but none were provided.'
);
}
}
return keys.length > 0 && keys[0][0] === '$';
}
export function resolveTimeoutOptions<T extends Partial<TimeoutContextOptions>>(
client: MongoClient,
options: T
): T &
Pick<
MongoClient['s']['options'],
'timeoutMS' | 'serverSelectionTimeoutMS' | 'waitQueueTimeoutMS' | 'socketTimeoutMS'
> {
const { socketTimeoutMS, serverSelectionTimeoutMS, waitQueueTimeoutMS, timeoutMS } =
client.s.options;View on GitHub (pinned to dce7939f86)