{"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/3366c21a6311e02f1be91da982f9b93d3cce99a0/src/cursor/abstract_cursor.ts#L608-L644","documentation":"Thrown by the deprecated cursor.forEach(iterator) when the iterator argument is not a function. forEach is a callback-pattern API; the driver invokes it once per document and a non-callable argument cannot be invoked.","triggerScenarios":"Calling cursor.forEach(null), cursor.forEach(undefined), cursor.forEach('doc => ...') (string instead of function), or passing an async function wrapped in quotes. Also passing an arrow function that was destructured/lost.","commonSituations":"Migrating from callback-style to async/await and forgetting to convert forEach to for-await; passing a method reference that was unbound and overridden; copy-paste leaving a string literal.","solutions":["Pass an actual function: cursor.forEach(doc => handle(doc)).","Prefer `for await (const doc of cursor)` — forEach is deprecated.","Double-check that bundlers/minifiers did not stringify the callback."],"exampleFix":"// before\ncursor.forEach('doc => handle(doc)');\n// after\nfor await (const doc of cursor) { handle(doc); }","handlingStrategy":"type-guard","validationCode":"if (typeof iterator !== 'function') throw new TypeError('iterator must be a function');\ncursor.forEach(iterator);","typeGuard":"function isFunction(v): v is Function { return typeof v === 'function'; }","tryCatchPattern":null,"preventionTips":["Migrate off the deprecated forEach to for-await-of.","Type the iterator parameter explicitly as (doc) => void | boolean.","Guard at API boundaries when accepting callbacks from callers."],"tags":["cursor","iteration","deprecated","misuse"],"analyzedSha":"3366c21a6311e02f1be91da982f9b93d3cce99a0","analyzedAt":"2026-08-04T13:40:15.335Z","schemaVersion":2}