mongodb/node-mongodb-native · error · MongoInvalidArgumentError

Argument "filter" must be an object

Error message

Argument "filter" must be an object

What it means

Thrown as a MongoInvalidArgumentError by the FindOneAndDeleteOperation constructor when the filter argument is null, undefined, or not an object type. findOneAndDelete requires a plain query document to identify the single document to remove. The check at find_and_modify.ts:205 is `filter == null || typeof filter !== 'object'`.

Solutions

  1. Pass a plain object filter, e.g. collection.findOneAndDelete({ _id: new ObjectId(id) }).
  2. To match any document use an empty object: collection.findOneAndDelete({}).
  3. Validate that the filter is a non-null object before calling the API.

Example fix

// before
await collection.findOneAndDelete(); // missing filter -> error

// after
await collection.findOneAndDelete({ _id: new ObjectId(id) });
Defensive patterns

Strategy: type-guard

Validate before calling

function isQueryObject(v: unknown): v is Record<string, unknown> {
  return typeof v === 'object' && v !== null && !Array.isArray(v);
}
if (!isQueryObject(filter)) {
  throw new TypeError('findOneAndDelete filter must be a plain object');
}
await collection.findOneAndDelete(filter);

Type guard

function isNonNullObject(v: unknown): v is Record<string, unknown> {
  return typeof v === 'object' && v !== null;
}

Prevention

When it happens

Trigger: Calling collection.findOneAndDelete(undefined), collection.findOneAndDelete(null), or with a primitive filter value. Note arrays pass the typeof check but are generally not valid query documents semantically.

Common situations: Omitting the filter argument; passing a string id; passing a variable that was never assigned from untyped input.

Related errors


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

Appendix: source

Thrown at src/operations/find_and_modify.ts:206

    if (options.hint) {
      command.hint = options.hint;
    }

    return command;
  }

  override handleOk(response: InstanceType<typeof this.SERVER_COMMAND_RESPONSE_TYPE>): Document {
    const result = super.handleOk(response);
    return this.options.includeResultMetadata ? result : (result.value ?? null);
  }
}

/** @internal */
export class FindOneAndDeleteOperation extends FindAndModifyOperation {
  constructor(collection: Collection, filter: Document, options: FindOneAndDeleteOptions) {
    // Basic validation
    if (filter == null || typeof filter !== 'object') {
      throw new MongoInvalidArgumentError('Argument "filter" must be an object');
    }

    super(collection, filter, options);
  }

  override buildCommandDocument(
    connection: Connection,
    session?: ClientSession
  ): Document & FindAndModifyCmdBase {
    const document = super.buildCommandDocument(connection, session);
    document.remove = true;
    return document;
  }
}

/** @internal */
export class FindOneAndReplaceOperation extends FindAndModifyOperation {
  private replacement: Document;

View on GitHub (pinned to dce7939f86)