mongodb/node-mongodb-native · error · MongoInvalidArgumentError
Update document requires atomic operators
Error message
Update document requires atomic operators
What it means
Thrown as a MongoInvalidArgumentError by the UpdateOneOperation constructor when the update document has no atomic operators (no key beginning with '$'). updateOne performs field-level modifications, so the update must contain operators like $set, $inc, $unset, or be an aggregation pipeline (which hasAtomicOperators treats via its options path). The check is `!hasAtomicOperators(update, options)` at update.ts:145.
Solutions
- Wrap changes in $set: collection.updateOne(filter, { $set: { field: value } }).
- If you meant a full-document replace, use collection.replaceOne(filter, replacement).
- For aggregation-based updates, pass a pipeline array of stages.
Example fix
// before
await collection.updateOne({ _id: id }, { status: 'done' });
// after
await collection.updateOne({ _id: id }, { $set: { status: 'done' } }); Defensive patterns
Strategy: validation
Validate before calling
function hasAtomicOperators(doc: Record<string, unknown>): boolean {
const keys = Object.keys(doc);
return keys.length > 0 && keys[0].startsWith('$');
}
if (!hasAtomicOperators(update)) {
throw new TypeError('updateOne update must contain atomic operators; for full replace use replaceOne');
}
await collection.updateOne(filter, update); Type guard
function isUpdateDoc(v: unknown): v is Record<string, unknown> {
return typeof v === 'object' && v !== null && !Array.isArray(v)
&& Object.keys(v).some(k => k.startsWith('$'));
} Prevention
- Wrap field changes in $set (or another operator) for updateOne.
- Use replaceOne for full-document replacement.
- Preflight operator checks help when updates come from user input.
When it happens
Trigger: Calling collection.updateOne(filter, { field: value }) with a plain replacement document instead of { $set: { field: value } }. Any update whose first key does not start with '$' triggers this.
Common situations: Confusing updateOne with replaceOne; forgetting the $set wrapper; passing a full document intended for replaceOne into updateOne.
Related errors
- Update document requires atomic operators
- Argument "update" must be an object
- Replacement document must not contain atomic operators
- Replacement document must not contain atomic operators
- Update document requires atomic operators
AI-assisted analysis of mongodb/node-mongodb-native@dce7939f86 (2026-08-11).
Data as JSON: /api/errors/3f49ebc88ecb27b8.
Report an issue: GitHub.
Appendix: source
Thrown at src/operations/update.ts:146
command.comment = options.comment;
}
return command;
}
}
/** @internal */
export class UpdateOneOperation extends UpdateOperation {
constructor(
ns: MongoDBCollectionNamespace,
filter: Document,
update: Document,
options: UpdateOptions
) {
super(ns, [makeUpdateStatement(filter, update, { ...options, multi: false })], options);
if (!hasAtomicOperators(update, options)) {
throw new MongoInvalidArgumentError('Update document requires atomic operators');
}
}
override handleOk(
response: InstanceType<typeof this.SERVER_COMMAND_RESPONSE_TYPE>
): UpdateResult {
const res = super.handleOk(response);
// @ts-expect-error Explain typing is broken
if (this.explain != null) return res;
if (res.code) throw new MongoServerError(res);
if (res.writeErrors) throw new MongoServerError(res.writeErrors[0]);
return {
acknowledged: this.writeConcern?.w !== 0,
modifiedCount: res.nModified ?? res.n,
upsertedId:View on GitHub (pinned to dce7939f86)