mongodb/node-mongodb-native · error · MongoInvalidArgumentError

Argument "update" must be an object

Error message

Argument "update" must be an object

What it means

FindOneAndUpdateOperation's constructor (src/operations/find_and_modify.ts:274) requires the `update` argument to be a non-null object. The update document (or aggregation pipeline) must be a plain object or array; null/undefined/string/number all throw a MongoInvalidArgumentError client-side. A subsequent check enforces that the update contains atomic operators or is a pipeline.

Source

Thrown at src/operations/find_and_modify.ts:274

}

/** @internal */
export class FindOneAndUpdateOperation extends FindAndModifyOperation {
  override options: FindOneAndUpdateOptions;

  private update: Document;
  constructor(
    collection: Collection,
    filter: Document,
    update: Document,
    options: FindOneAndUpdateOptions
  ) {
    if (filter == null || typeof filter !== 'object') {
      throw new MongoInvalidArgumentError('Argument "filter" must be an object');
    }

    if (update == null || typeof update !== 'object') {
      throw new MongoInvalidArgumentError('Argument "update" must be an object');
    }

    if (!hasAtomicOperators(update, options)) {
      throw new MongoInvalidArgumentError('Update document requires atomic operators');
    }

    super(collection, filter, options);
    this.update = update;
    this.options = options;
  }

  override buildCommandDocument(
    connection: Connection,
    session?: ClientSession
  ): Document & FindAndModifyCmdBase {
    const document = super.buildCommandDocument(connection, session);
    document.update = this.update;
    configureFindAndModifyCmdBaseUpdateOpts(document, this.options);

View on GitHub (pinned to 3366c21a63)

Solutions

  1. Pass an update document with atomic operators: collection.findOneAndUpdate(filter, { $set: { field: value } }).
  2. Or pass an aggregation pipeline array for expressive updates.
  3. Ensure the update variable is a defined object/array before the call.

Example fix

// before
await collection.findOneAndUpdate({ _id }, 'new value');

// after
await collection.findOneAndUpdate({ _id }, { $set: { value: 'new value' } });
Defensive patterns

Strategy: validation

Validate before calling

function assertUpdate(update: unknown): asserts update is Record<string, unknown> {
  if (update == null || typeof update !== 'object') {
    throw new TypeError('findOneAndUpdate: update must be an object or pipeline');
  }
}

Type guard

const isValidUpdate = (u: unknown): u is Record<string, unknown> | unknown[] =>
  u != null && typeof u === 'object';

Prevention

When it happens

Trigger: Calling collection.findOneAndUpdate(filter, null), collection.findOneAndUpdate(filter, undefined), or passing a primitive/string as the update.

Common situations: Omitting the update argument, passing a field value instead of an update document, or destructuring undefined from a request payload.

Related errors


AI-assisted analysis of mongodb/node-mongodb-native@3366c21a63 (2026-08-04). Data as JSON: /data/errors/c9eb0168fd25ed18.json. Report an issue: GitHub.