{"record":{"id":"00238d7a10476b29","repo":"mongodb/node-mongodb-native","slug":"argument-iterator-must-be-a-function","errorCode":null,"errorMessage":"Argument \"iterator\" must be a function","messagePattern":"Argument \"iterator\" must be a function","errorType":"exception","errorClass":"MongoInvalidArgumentError","httpStatus":null,"severity":"error","filePath":"src/cursor/abstract_cursor.ts","lineNumber":626,"sourceCode":"      }\n    }\n\n    return null;\n  }\n\n  /**\n   * Iterates over all the documents for this cursor using the iterator, callback pattern.\n   *\n   * If the iterator returns `false`, iteration will stop.\n   *\n   * @param iterator - The iteration callback.\n   * @deprecated - Will be removed in a future release. Use for await...of instead.\n   */\n  async forEach(iterator: (doc: TSchema) => boolean | void): Promise<void> {\n    this.signal?.throwIfAborted();\n\n    if (typeof iterator !== 'function') {\n      throw new MongoInvalidArgumentError('Argument \"iterator\" must be a function');\n    }\n    for await (const document of this) {\n      const result = iterator(document);\n      if (result === false) {\n        break;\n      }\n    }\n  }\n\n  /**\n   * Frees any client-side resources used by the cursor.\n   */\n  async close(options?: { timeoutMS?: number }): Promise<void> {\n    await this.cleanup(options?.timeoutMS);\n  }\n\n  /**\n   * Returns an array of documents. The caller is responsible for making sure that there","sourceCodeStart":608,"sourceCodeEnd":644,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/dce7939f86fb283e167ad709955abedb7bf23124/src/cursor/abstract_cursor.ts#L608-L644","documentation":"Thrown as a MongoInvalidArgumentError from forEach() when the iterator argument fails `typeof iterator !== 'function'`. forEach() drives iteration by invoking the callback once per document and stopping when it returns false, so a non-callable argument would fail at the first document at runtime; the constructor-style guard fails fast with a precise message instead. The method is also deprecated in favor of for-await iteration.","triggerScenarios":"Calling cursor.forEach(undefined), cursor.forEach(null), cursor.forEach('doc => {}') (string instead of function), or cursor.forEach(someObject); passing a value that was supposed to be a callback but was conditionally undefined.","commonSituations":"Refactoring a forEach call and forgetting to pass the callback; passing a function name that is typo'd or shadowed to undefined; mixing callback-style and async-iterator styles.","solutions":["Pass an actual function: cursor.forEach(doc => { ... }).","Migrate to for await (const doc of cursor) { ... } which is the non-deprecated replacement.","If the callback is optional in your code, default it to a no-op function or branch before calling forEach()."],"exampleFix":"// before: callback is undefined / not a function\nawait cursor.forEach(processDocs); // processDocs is undefined\n\n// after: pass a real function, or use for-await\nawait cursor.forEach(doc => handle(doc));\n// preferred:\nfor await (const doc of cursor) handle(doc);","handlingStrategy":"type-guard","validationCode":"if (typeof iterator !== 'function') {\n  throw new TypeError('forEach requires a function argument');\n}\nawait cursor.forEach(iterator);","typeGuard":"function isIterator(v: unknown): v is (doc: any) => boolean | void {\n  return typeof v === 'function';\n}","tryCatchPattern":null,"preventionTips":["Migrate from the deprecated forEach() to for-await.","Always pass a function literal directly to forEach().","Default optional callbacks to a no-op function."],"tags":["cursor","for-each","deprecated","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"}