mongodb/node-mongodb-native · error · MongoAPIError
Client bulk write replace models must not contain atomic mod
Error message
Client bulk write replace models must not contain atomic modifiers (start with $) and must not be empty.
What it means
Thrown when building a replaceOne model if the replacement document is empty or contains keys starting with '$'. Per spec, replaceOne MUST be a full replacement document (no atomic operators); if you want $ operators use updateOne/updateMany. Classified as MongoAPIError.
Source
Thrown at src/operations/client_bulk_write/command_builder.ts:440
updateMods: WithoutId<Document>;
hint?: Hint;
upsert?: boolean;
collation?: CollationOptions;
sort?: SortForCmd;
}
/**
* Build the replace one operation.
* @param model - The replace one model.
* @param index - The namespace index.
* @returns the operation.
*/
export const buildReplaceOneOperation = (
model: ClientReplaceOneModel<Document>,
index: number
): ClientReplaceOneOperation => {
if (hasAtomicOperators(model.replacement)) {
throw new MongoAPIError(
'Client bulk write replace models must not contain atomic modifiers (start with $) and must not be empty.'
);
}
const document: ClientReplaceOneOperation = {
update: index,
multi: false,
filter: model.filter,
updateMods: model.replacement
};
if (model.hint) {
document.hint = model.hint;
}
if (model.upsert) {
document.upsert = model.upsert;
}
if (model.collation) {
document.collation = model.collation;View on GitHub (pinned to 3366c21a63)
Solutions
- Provide a non-empty replacement document without any '$'-prefixed keys.
- If you need atomic operators, switch the model name to updateOne/updateMany.
- Validate: assert Object.keys(replacement).length > 0 && !Object.keys(replacement)[0].startsWith('$').
Example fix
// before
await client.bulkWrite([{
namespace: 'db.coll',
name: 'replaceOne',
filter: { _id: 1 },
replacement: { $set: { a: 1 } } // wrong
}]);
// after
await client.bulkWrite([{
namespace: 'db.coll',
name: 'replaceOne',
filter: { _id: 1 },
replacement: { a: 1 }
}]); Defensive patterns
Strategy: validation
Validate before calling
function isValidReplacement(doc) {
const keys = Object.keys(doc);
return keys.length > 0 && keys.every(k => !k.startsWith('$'));
} Type guard
function isPlainReplacement(v): boolean {
return v != null && typeof v === 'object' && Object.keys(v).every(k => !k.startsWith('$'));
} Prevention
- replaceOne takes a plain document, no $ operators
- Switch to updateOne if you need $set
- Validate replacement is non-empty and operator-free
When it happens
Trigger: Passing client.bulkWrite() a replaceOne model whose replacement is { $set: {...} } or {}. Mixing up updateOne and replaceOne semantics.
Common situations: Switching from updateOne to replaceOne but leaving $set; passing an empty replacement built from a failed mapping.
Related errors
- Replacement document must not use atomic operators
- Client bulk write update models must only contain atomic mod
- No client bulk write models were provided.
- Update document requires atomic operators
- Bulk find operation must specify a selector
AI-assisted analysis of mongodb/node-mongodb-native@3366c21a63 (2026-08-04).
Data as JSON: /data/errors/70d6fb31c2b63700.json.
Report an issue: GitHub.