mongodb/node-mongodb-native · error · MongoInvalidArgumentError
is not a valid query modifier
Error message
${name} is not a valid query modifier What it means
Thrown by FindCursor.addQueryModifier when the name argument does not begin with '$'. Query modifiers are raw wire-protocol fields like $orderby, $hint, $maxTimeMS, so the driver requires the leading dollar sign. This is a sanity check before it strips the '$' to map the modifier to a typed findOptions field.
Solutions
- Prefix the modifier name with '$': addQueryModifier('$orderby', value).
- Prefer the typed API instead: cursor.sort(), cursor.hint(), cursor.maxTimeMS() rather than addQueryModifier.
- If the name is dynamic, ensure it is normalized with `name.startsWith('$') ? name : '$' + name`.
Example fix
// before
cursor.addQueryModifier('orderby', { age: 1 });
// after
cursor.sort({ age: 1 });
// or
cursor.addQueryModifier('$orderby', { age: 1 }); Defensive patterns
Strategy: validation
Validate before calling
function addModifier(cursor, name, value) {
if (!name.startsWith('$')) name = '$' + name;
return cursor.addQueryModifier(name, value);
} Type guard
function isValidModifierName(name) { return typeof name === 'string' && name.startsWith('$'); } Prevention
- Prefer typed methods (cursor.sort, cursor.hint, cursor.comment) over addQueryModifier.
- Normalize dynamic modifier names with a leading '$' before calling addQueryModifier.
When it happens
Trigger: cursor.addQueryModifier('orderby', { age: 1 }) instead of '$orderby'; passing a field name from a user-supplied string that was not normalized; building a modifier name dynamically without prefixing '$'.
Common situations: Translating a human-readable sort hint into a query modifier; using addQueryModifier instead of the typed .sort()/.hint() methods; code that strips '$' upstream and forgets to re-add it.
Related errors
- Invalid query modifier
- Invalid first parameter to count
- Option "allowDiskUse" requires a sort specification
- timeoutMS cannot be used with explain when explain is…
- Argument for maxAwaitTimeMS must be a number
AI-assisted analysis of mongodb/node-mongodb-native@dce7939f86 (2026-08-11).
Data as JSON: /api/errors/0bcaf239cb3fc7ea.
Report an issue: GitHub.
Appendix: source
Thrown at src/cursor/find_cursor.ts:268
*
* @param value - The $showDiskLoc option has now been deprecated and replaced with the showRecordId field. $showDiskLoc will still be accepted for OP_QUERY stye find.
*/
showRecordId(value: boolean): this {
this.throwIfInitialized();
this.findOptions.showRecordId = value;
return this;
}
/**
* Add a query modifier to the cursor query
*
* @param name - The query modifier (must start with $, such as $orderby etc)
* @param value - The modifier value.
*/
addQueryModifier(name: string, value: string | boolean | number | Document): this {
this.throwIfInitialized();
if (name[0] !== '$') {
throw new MongoInvalidArgumentError(`${name} is not a valid query modifier`);
}
// Strip of the $
const field = name.substr(1);
// NOTE: consider some TS magic for this
switch (field) {
case 'comment':
this.findOptions.comment = value;
break;
case 'explain':
this.findOptions.explain = value as boolean;
break;
case 'hint':
this.findOptions.hint = value as string | Document;
break;View on GitHub (pinned to dce7939f86)