{"record":{"id":"bed84e3365b5b59c","repo":"mongodb/node-mongodb-native","slug":"cannot-set-timeoutmode-without-setting-timeoutms","errorCode":null,"errorMessage":"Cannot set timeoutMode without setting timeoutMS","messagePattern":"Cannot set timeoutMode without setting timeoutMS","errorType":"exception","errorClass":"MongoInvalidArgumentError","httpStatus":null,"severity":"error","filePath":"src/cursor/abstract_cursor.ts","lineNumber":310,"sourceCode":"                'Cannot specify maxAwaitTimeMS >= timeoutMS for a tailable awaitData cursor'\n              );\n          }\n\n          this.cursorOptions.timeoutMode = CursorTimeoutMode.ITERATION;\n        } else {\n          this.cursorOptions.timeoutMode = CursorTimeoutMode.LIFETIME;\n        }\n      } else {\n        if (options.tailable && options.timeoutMode === CursorTimeoutMode.LIFETIME) {\n          throw new MongoInvalidArgumentError(\n            \"Cannot set tailable cursor's timeoutMode to LIFETIME\"\n          );\n        }\n        this.cursorOptions.timeoutMode = options.timeoutMode;\n      }\n    } else {\n      if (options.timeoutMode != null)\n        throw new MongoInvalidArgumentError('Cannot set timeoutMode without setting timeoutMS');\n    }\n\n    // Set for initial command\n    this.cursorOptions.omitMaxTimeMS =\n      this.cursorOptions.timeoutMS != null &&\n      ((this.cursorOptions.timeoutMode === CursorTimeoutMode.ITERATION &&\n        !this.cursorOptions.tailable) ||\n        (this.cursorOptions.tailable && !this.cursorOptions.awaitData));\n\n    const readConcern = ReadConcern.fromOptions(options);\n    if (readConcern) {\n      this.cursorOptions.readConcern = readConcern;\n    }\n\n    if (typeof options.batchSize === 'number') {\n      this.cursorOptions.batchSize = options.batchSize;\n    }\n","sourceCodeStart":292,"sourceCodeEnd":328,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/dce7939f86fb283e167ad709955abedb7bf23124/src/cursor/abstract_cursor.ts#L292-L328","documentation":"Thrown as a MongoInvalidArgumentError in the AbstractCursor constructor when timeoutMode is supplied but timeoutMS is not. timeoutMode only describes how an existing timeoutMS deadline is applied (per-iteration vs whole-cursor), so it is meaningless without a deadline. The constructor explicitly checks `options.timeoutMode != null` only in the `else` branch where `timeoutMS` is absent, and rejects the pairing to prevent silent no-op configuration.","triggerScenarios":"collection.find(filter, { timeoutMode: 'iteration' }) with no timeoutMS; passing a shared options object that sets timeoutMode but whose timeoutMS was conditionally deleted/undefined.","commonSituations":"Refactoring timeout code and dropping the timeoutMS line while leaving timeoutMode; spreading a base options object that always includes timeoutMode but only sometimes includes timeoutMS.","solutions":["Always set timeoutMS whenever you set timeoutMode.","If you do not want a timeout, remove both timeoutMS and timeoutMode.","Centralize timeout config so timeoutMode is only assigned together with a finite timeoutMS."],"exampleFix":"// before: timeoutMode with no deadline\nconst cursor = collection.find(filter, { timeoutMode: 'iteration' });\n\n// after: provide the deadline the mode applies to\nconst cursor = collection.find(filter, { timeoutMS: 1000, timeoutMode: 'iteration' });","handlingStrategy":"validation","validationCode":"if (opts.timeoutMode != null && opts.timeoutMS == null) {\n  throw new RangeError('timeoutMode requires timeoutMS to be set as well.');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pair timeoutMode with a finite timeoutMS.","If you do not want a timeout, omit both options.","Type your options builder so timeoutMode can only be set through a helper that also sets timeoutMS."],"tags":["cursor","csot","timeout","timeout-mode","invalid-argument"],"backgroundTag":null,"analyzedSha":"dce7939f86fb283e167ad709955abedb7bf23124","analyzedAt":"2026-08-11T04:54:53.215Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}