{"record":{"id":"dab3da28dafe6878","repo":"mongodb/node-mongodb-native","slug":"tailable-cursor-does-not-support-limit","errorCode":null,"errorMessage":"Tailable cursor does not support limit","messagePattern":"Tailable cursor does not support limit","errorType":"exception","errorClass":"MongoTailableCursorError","httpStatus":null,"severity":"error","filePath":"src/cursor/find_cursor.ts","lineNumber":468,"sourceCode":"   * Set the collation options for the cursor.\n   *\n   * @param value - The cursor collation options (MongoDB 3.4 or higher) settings for update operation (see 3.4 documentation for available fields).\n   */\n  collation(value: CollationOptions): this {\n    this.throwIfInitialized();\n    this.findOptions.collation = value;\n    return this;\n  }\n\n  /**\n   * Set the limit for the cursor.\n   *\n   * @param value - The limit for the cursor query.\n   */\n  limit(value: number): this {\n    this.throwIfInitialized();\n    if (this.findOptions.tailable) {\n      throw new MongoTailableCursorError('Tailable cursor does not support limit');\n    }\n\n    if (typeof value !== 'number') {\n      throw new MongoInvalidArgumentError('Operation \"limit\" requires an integer');\n    }\n\n    this.findOptions.limit = value;\n    return this;\n  }\n\n  /**\n   * Set the skip for the cursor.\n   *\n   * @param value - The skip for the cursor query.\n   */\n  skip(value: number): this {\n    this.throwIfInitialized();\n    if (this.findOptions.tailable) {","sourceCodeStart":450,"sourceCodeEnd":486,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/dce7939f86fb283e167ad709955abedb7bf23124/src/cursor/find_cursor.ts#L450-L486","documentation":"Thrown by FindCursor.limit when findOptions.tailable is true. Tailable cursors follow an open-ended live stream from a capped collection and there is no well-defined point at which to stop on a document count; applying a limit would close the cursor prematurely and miss subsequent inserts. Subclass MongoTailableCursorError.","triggerScenarios":"collection.find({}, { tailable: true }).limit(100); setting tailable via options then calling .limit(); trying to read only the first N entries from an oplog tail.","commonSituations":"Reusing a find-query builder that always applies a default limit; converting a bounded query to a tailable stream without dropping limit.","solutions":["Remove .limit() from the tailable cursor and bound consumption client-side (e.g. break out of the for-await loop after N docs).","If you need a bounded read, use a non-tailable query on the capped collection instead.","Use a Change Stream with a bounded consumer instead."],"exampleFix":"// before\ncollection.find({}, { tailable: true }).limit(100);\n\n// after\nconst cursor = collection.find({}, { tailable: true });\nlet count = 0;\nfor await (const doc of cursor) {\n  if (++count > 100) break;\n  handle(doc);\n}","handlingStrategy":"validation","validationCode":"function safeLimit(cursor, value, opts) {\n  if (opts?.tailable) throw new Error('Cannot limit a tailable cursor; bound consumption in the loop');\n  return cursor.limit(value);\n}","typeGuard":"function isTailableCursor(opts) { return Boolean(opts?.tailable); }","tryCatchPattern":null,"preventionTips":["Bound tailable consumption client-side with a counter in the for-await loop.","Filter with { ts: { $gt: lastSeen } } rather than limit when tailing."],"tags":["find","tailable","capped-collection","limit"],"backgroundTag":null,"analyzedSha":"dce7939f86fb283e167ad709955abedb7bf23124","analyzedAt":"2026-08-11T04:54:53.215Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}