{"record":{"id":"0ad9484ef35a494f","repo":"mongodb/node-mongodb-native","slug":"argument-for-maxtimems-must-be-a-number","errorCode":null,"errorMessage":"Argument for maxTimeMS must be a number","messagePattern":"Argument for maxTimeMS must be a number","errorType":"exception","errorClass":"MongoInvalidArgumentError","httpStatus":null,"severity":"error","filePath":"src/cursor/abstract_cursor.ts","lineNumber":789,"sourceCode":"  withReadConcern(readConcern: ReadConcernLike): this {\n    this.throwIfInitialized();\n    const resolvedReadConcern = ReadConcern.fromOptions({ readConcern });\n    if (resolvedReadConcern) {\n      this.cursorOptions.readConcern = resolvedReadConcern;\n    }\n\n    return this;\n  }\n\n  /**\n   * Set a maxTimeMS on the cursor query, allowing for hard timeout limits on queries (Only supported on MongoDB 2.6 or higher)\n   *\n   * @param value - Number of milliseconds to wait before aborting the query.\n   */\n  maxTimeMS(value: number): this {\n    this.throwIfInitialized();\n    if (typeof value !== 'number') {\n      throw new MongoInvalidArgumentError('Argument for maxTimeMS must be a number');\n    }\n\n    this.cursorOptions.maxTimeMS = value;\n    return this;\n  }\n\n  /**\n   * Set the batch size for the cursor.\n   *\n   * @param value - The number of documents to return per batch. See {@link https://www.mongodb.com/docs/manual/reference/command/find/|find command documentation}.\n   */\n  batchSize(value: number): this {\n    this.throwIfInitialized();\n    if (this.cursorOptions.tailable) {\n      throw new MongoTailableCursorError('Tailable cursor does not support batchSize');\n    }\n\n    if (typeof value !== 'number') {","sourceCodeStart":771,"sourceCodeEnd":807,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/dce7939f86fb283e167ad709955abedb7bf23124/src/cursor/abstract_cursor.ts#L771-L807","documentation":"Thrown as a MongoInvalidArgumentError from maxTimeMS() when the value argument fails `typeof value !== 'number'`. maxTimeMS sets a server-side time limit on the initial cursor-creating command (find/aggregate/listCollections), encoded as a BSON int32, so a non-number cannot be serialized. The method also requires the cursor not be initialized yet. Note this is the legacy per-command maxTimeMS; with CSOT (timeoutMS) the driver manages maxTimeMS internally.","triggerScenarios":"cursor.maxTimeMS('5000'); cursor.maxTimeMS(undefined); cursor.maxTimeMS(5000n) (BigInt is not a number).","commonSituations":"Reading timeout values from env/config as strings and passing them unconverted; mixing BigInt timestamps with millisecond numbers; passing a value typed as string|number without narrowing.","solutions":["Pass a finite number of milliseconds: cursor.maxTimeMS(5000).","Parse config strings first: cursor.maxTimeMS(Number(process.env.CURSOR_TIMEOUT_MS)).","If migrating to CSOT, set timeoutMS on the cursor options instead and let the driver derive maxTimeMS."],"exampleFix":"// before: string from config\nconst ms = process.env.MAX_TIME_MS; // '5000'\ncursor.maxTimeMS(ms);\n\n// after: parse to a number\ncursor.maxTimeMS(Number(process.env.MAX_TIME_MS ?? 5000));","handlingStrategy":"type-guard","validationCode":"if (typeof value !== 'number' || !Number.isFinite(value)) {\n  throw new TypeError('maxTimeMS must be a finite number');\n}\ncursor.maxTimeMS(value);","typeGuard":"function isFiniteNumber(v: unknown): v is number {\n  return typeof v === 'number' && Number.isFinite(v);\n}","tryCatchPattern":null,"preventionTips":["Parse config strings with Number() before passing.","Avoid BigInt values for millisecond timeouts.","Consider migrating to timeoutMS (CSOT) instead of manual maxTimeMS."],"tags":["cursor","max-time-ms","invalid-argument","typescript"],"backgroundTag":null,"analyzedSha":"dce7939f86fb283e167ad709955abedb7bf23124","analyzedAt":"2026-08-11T04:54:53.215Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}