mongodb/node-mongodb-native · error · MongoTailableCursorError

Tailable cursor does not support skip

Error message

Tailable cursor does not support skip

What it means

Thrown by FindCursor.skip when findOptions.tailable is true. Skip on a tailable cursor is meaningless because the cursor follows live inserts in natural order; skipping N documents at cursor open does not correspond to a stable position in the stream. Subclass MongoTailableCursorError.

Solutions

  1. Remove .skip() from the tailable cursor; track a resume token / timestamp on the client instead.
  2. Use a non-tailable query if you need offset pagination.
  3. Filter with a query (e.g. { ts: { $gt: lastSeen } }) instead of skipping.

Example fix

// before
collection.find({}, { tailable: true }).skip(50);

// after
collection.find({ ts: { $gt: lastSeenTs } }, { tailable: true });
Defensive patterns

Strategy: validation

Validate before calling

function safeSkip(cursor, value, opts) {
  if (opts?.tailable) throw new Error('Cannot skip on a tailable cursor; filter by resume marker');
  return cursor.skip(value);
}

Type guard

function isTailableCursor(opts) { return Boolean(opts?.tailable); }

Prevention

When it happens

Trigger: collection.find({}, { tailable: true }).skip(50); setting tailable via addCursorFlag then calling .skip(); applying pagination defaults to a tailing query.

Common situations: A shared query builder that injects skip for pagination on every find; converting a paginated query to tailable without removing skip.

Related errors


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

Appendix: source

Thrown at src/cursor/find_cursor.ts:487

    }

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

    this.findOptions.limit = value;
    return this;
  }

  /**
   * Set the skip for the cursor.
   *
   * @param value - The skip for the cursor query.
   */
  skip(value: number): this {
    this.throwIfInitialized();
    if (this.findOptions.tailable) {
      throw new MongoTailableCursorError('Tailable cursor does not support skip');
    }

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

    this.findOptions.skip = value;
    return this;
  }
}

View on GitHub (pinned to dce7939f86)