mongodb/node-mongodb-native · error · MongoInvalidArgumentError

Bulk find operation must specify a selector

Error message

Bulk find operation must specify a selector

What it means

Thrown as MongoInvalidArgumentError by BulkOperationBase.find() (src/bulk/common.ts:1057) when no selector (filter) is supplied. find(selector) stores the selector for subsequent update/delete/replace calls; a missing selector means there is no query to scope those operations to, so the driver refuses to build them.

Solutions

  1. Pass an explicit filter document: bulk.find({ userId: 42 }).
  2. If you genuinely mean 'all documents', pass an empty query: bulk.find({}).updateOne({...}) (and reconsider whether a targeted filter is safer).
  3. Initialize the filter variable with a default of {} so it is never undefined.

Example fix

// before
bulk.find().updateOne({ $set: { archived: true } });

// after
bulk.find({}).updateOne({ $set: { archived: true } });
Defensive patterns

Strategy: validation

Validate before calling

function ensureSelector(selector: unknown) {
  if (!selector || typeof selector !== 'object' || Array.isArray(selector)) {
    throw new Error('bulk.find() requires a non-null filter document; use {} for all docs');
  }
  return selector as Record<string, unknown>;
}

bulk.find(ensureSelector(maybeFilter)).updateOne({ $set: { a: 1 } });

Type guard

function isFilterDocument(sel: unknown): sel is Record<string, unknown> {
  return sel != null && typeof sel === 'object' && !Array.isArray(sel);
}

Try / catch

try {
  bulk.find(filter).updateOne({ $set: { a: 1 } });
} catch (e) {
  if (e instanceof MongoInvalidArgumentError && /must specify a selector/.test(e.message)) {
    bulk.find({}).updateOne({ $set: { a: 1 } });
  } else throw e;
}

Prevention

When it happens

Trigger: Calling bulk.find() with no argument, or bulk.find(null)/bulk.find(undefined) when a variable holding the filter was not assigned. Guarded by `if (!selector)` at src/bulk/common.ts:1056.

Common situations: Filter variable computed conditionally and left undefined, a destructuring bug that drops the filter, or an assumption that find() with no args matches all documents (it does not — pass {} explicitly for that).

Related errors


AI-assisted analysis of mongodb/node-mongodb-native@dce7939f86 (2026-08-11). Data as JSON: /api/errors/3f944425ec7bdf72. Report an issue: GitHub.

Appendix: source

Thrown at src/bulk/common.ts:1057

   *
   * // Add a multi deletion
   * bulkOp.find({ h: 8 }).delete();
   *
   * // Add a replaceOne
   * bulkOp.find({ i: 9 }).replaceOne({writeConcern: { j: 10 }});
   *
   * // Update using a pipeline
   * bulk.find({ k: 11, y: { $exists: true }, z: { $exists: true } }).updateOne([
   *   { $set: { total: { $sum: [ '$y', '$z' ] } } }
   * ]);
   *
   * // All of the ops will now be executed
   * await bulkOp.execute();
   * ```
   */
  find(selector: Document): FindOperators {
    if (!selector) {
      throw new MongoInvalidArgumentError('Bulk find operation must specify a selector');
    }

    // Save a current selector
    this.s.currentOp = {
      selector: selector
    };

    return new FindOperators(this);
  }

  /** Specifies a raw operation to perform in the bulk write. */
  raw(op: AnyBulkWriteOperation): this {
    if (op == null || typeof op !== 'object') {
      throw new MongoInvalidArgumentError('Operation must be an object with an operation key');
    }
    if ('insertOne' in op) {
      const forceServerObjectId = this.shouldForceServerObjectId();
      const document =

View on GitHub (pinned to dce7939f86)