mongodb/node-mongodb-native · error · MongoInvalidArgumentError

Cannot set timeoutMode without setting timeoutMS

Error message

Cannot set timeoutMode without setting timeoutMS

What it means

Thrown when timeoutMode is set but timeoutMS is null/undefined. The timeoutMode option is only meaningful as a sub-property of CSOT (Client-Side Operation Timeout) and has no effect without a timeoutMS budget.

Source

Thrown at src/cursor/abstract_cursor.ts:310

                'Cannot specify maxAwaitTimeMS >= timeoutMS for a tailable awaitData cursor'
              );
          }

          this.cursorOptions.timeoutMode = CursorTimeoutMode.ITERATION;
        } else {
          this.cursorOptions.timeoutMode = CursorTimeoutMode.LIFETIME;
        }
      } else {
        if (options.tailable && options.timeoutMode === CursorTimeoutMode.LIFETIME) {
          throw new MongoInvalidArgumentError(
            "Cannot set tailable cursor's timeoutMode to LIFETIME"
          );
        }
        this.cursorOptions.timeoutMode = options.timeoutMode;
      }
    } else {
      if (options.timeoutMode != null)
        throw new MongoInvalidArgumentError('Cannot set timeoutMode without setting timeoutMS');
    }

    // Set for initial command
    this.cursorOptions.omitMaxTimeMS =
      this.cursorOptions.timeoutMS != null &&
      ((this.cursorOptions.timeoutMode === CursorTimeoutMode.ITERATION &&
        !this.cursorOptions.tailable) ||
        (this.cursorOptions.tailable && !this.cursorOptions.awaitData));

    const readConcern = ReadConcern.fromOptions(options);
    if (readConcern) {
      this.cursorOptions.readConcern = readConcern;
    }

    if (typeof options.batchSize === 'number') {
      this.cursorOptions.batchSize = options.batchSize;
    }

View on GitHub (pinned to 3366c21a63)

Solutions

  1. Always set timeoutMS when setting timeoutMode.
  2. Remove timeoutMode if you are not using CSOT — the driver infers mode from timeoutMS presence.
  3. Build options with a helper that sets both together or neither.

Example fix

// before
collection.find(filter, { timeoutMode: CursorTimeoutMode.LIFETIME });
// after
collection.find(filter, { timeoutMS: 5000, timeoutMode: CursorTimeoutMode.LIFETIME });
Defensive patterns

Strategy: validation

Validate before calling

function checkModeHasTimeout(opts) {
  if (opts.timeoutMode != null && opts.timeoutMS == null) return false;
  return true;
}

Prevention

When it happens

Trigger: Passing { timeoutMode: CursorTimeoutMode.LIFETIME } without a timeoutMS, or copying a config object that set timeoutMode but had timeoutMS stripped/overridden to undefined.

Common situations: Spreading a default-options object that includes timeoutMode then conditionally deleting timeoutMS; partial config from env where TIMEOUT_MS env var was unset.

Related errors


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