mongodb/node-mongodb-native · error · MongoTailableCursorError

Tailable cursor does not support batchSize

Error message

Tailable cursor does not support batchSize

What it means

MongoTailableCursorError thrown by cursor.batchSize(value) when the cursor is tailable. Tailable cursors stream documents from a capped collection and the server ignores batchSize for them; the driver enforces this to prevent surprising behavior. The check fires before the type check on value.

Source

Thrown at src/cursor/abstract_cursor.ts:804

  maxTimeMS(value: number): this {
    this.throwIfInitialized();
    if (typeof value !== 'number') {
      throw new MongoInvalidArgumentError('Argument for maxTimeMS must be a number');
    }

    this.cursorOptions.maxTimeMS = value;
    return this;
  }

  /**
   * Set the batch size for the cursor.
   *
   * @param value - The number of documents to return per batch. See {@link https://www.mongodb.com/docs/manual/reference/command/find/|find command documentation}.
   */
  batchSize(value: number): this {
    this.throwIfInitialized();
    if (this.cursorOptions.tailable) {
      throw new MongoTailableCursorError('Tailable cursor does not support batchSize');
    }

    if (typeof value !== 'number') {
      throw new MongoInvalidArgumentError('Operation "batchSize" requires an integer');
    }

    this.cursorOptions.batchSize = value;
    return this;
  }

  /**
   * Rewind this cursor to its uninitialized state. Any options that are present on the cursor will
   * remain in effect. Iterating this cursor will cause new queries to be sent to the server, even
   * if the resultant data has already been retrieved by this cursor.
   */
  rewind(): void {
    if (this.timeoutContext && this.timeoutContext.owner !== this) {
      throw new MongoAPIError(`Cannot rewind cursor that does not own its timeout context.`);

View on GitHub (pinned to 3366c21a63)

Solutions

  1. Remove the batchSize call/config when the cursor is tailable.
  2. To control getMore cadence on a tailable awaitData cursor, use maxAwaitTimeMS instead.
  3. Split your query builder so tailable queries omit batchSize.

Example fix

// before
cursor.addCursorFlag('tailable', true).addCursorFlag('awaitData', true).batchSize(100);
// after
cursor.addCursorFlag('tailable', true).addCursorFlag('awaitData', true).maxAwaitTimeMS(1000);
Defensive patterns

Strategy: validation

Validate before calling

if (cursorOptions.tailable) throw new Error('do not set batchSize on tailable cursor');

Prevention

When it happens

Trigger: Calling cursor.addCursorFlag('tailable', true) followed by cursor.batchSize(100), or constructing with { tailable: true } then calling batchSize(). Also affects awaitData tailable cursors (change-stream-like patterns on capped collections).

Common situations: Reusing a find-options builder that always sets batchSize across all queries; migrating a normal find to a tailable find without removing batchSize; assuming batchSize controls getMore cadence on a tailable cursor (use maxAwaitTimeMS instead).

Related errors


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