{"id":"e0fb990ab93f3ccb","repo":"mongodb/node-mongodb-native","slug":"argument-docs-must-be-an-array-of-documents","errorCode":null,"errorMessage":"Argument \"docs\" must be an array of documents","messagePattern":"Argument \"docs\" must be an array of documents","errorType":"exception","errorClass":"MongoInvalidArgumentError","httpStatus":null,"severity":"error","filePath":"src/collection.ts","lineNumber":317,"sourceCode":"        resolveOptions(this, options)\n      ) as TODO_NODE_3286\n    );\n  }\n\n  /**\n   * Inserts an array of documents into MongoDB. If documents passed in do not contain the **_id** field,\n   * one will be added to each of the documents missing it by the driver, mutating the document. This behavior\n   * can be overridden by setting the **forceServerObjectId** flag.\n   *\n   * @param docs - The documents to insert\n   * @param options - Optional settings for the command\n   */\n  async insertMany(\n    docs: ReadonlyArray<OptionalUnlessRequiredId<TSchema>>,\n    options?: BulkWriteOptions\n  ): Promise<InsertManyResult<TSchema>> {\n    if (!Array.isArray(docs)) {\n      throw new MongoInvalidArgumentError('Argument \"docs\" must be an array of documents');\n    }\n    options = resolveOptions(this, options ?? {});\n\n    const acknowledged = WriteConcern.fromOptions(options)?.w !== 0;\n\n    try {\n      const res = await this.bulkWrite(\n        docs.map(doc => ({ insertOne: { document: doc } })),\n        options\n      );\n      return {\n        acknowledged,\n        insertedCount: res.insertedCount,\n        insertedIds: res.insertedIds\n      };\n    } catch (err) {\n      if (err && err.message === 'Operation must be an object with an operation key') {\n        throw new MongoInvalidArgumentError(","sourceCodeStart":299,"sourceCodeEnd":335,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/3366c21a6311e02f1be91da982f9b93d3cce99a0/src/collection.ts#L299-L335","documentation":"Thrown by Collection.insertMany() when the first argument is not an Array. The driver wraps each provided document into an { insertOne: { document } } bulk operation, so it must iterate the input; a non-iterable value cannot be processed. This is a MongoInvalidArgumentError raised before any network call. The TypeScript signature already requires ReadonlyArray<OptionalUnlessRequiredId<TSchema>>, so this signals a type-safety escape (any/unknown) or a runtime-only caller.","triggerScenarios":"Calling collection.insertMany(singleDoc) passing a single object instead of an array; passing undefined/null when the array is conditionally built; passing a Map, Set, or other iterable that is not an Array (Array.isArray returns false); passing a Promise that resolved to an array but was not awaited.","commonSituations":"JavaScript callers that forgot to wrap a single document in []; a value sourced from JSON.parse or an untyped API response fed directly in; refactoring from insertOne to insertMany without adjusting the call site; awaiting an async iterator's result incorrectly.","solutions":["Wrap the value in an array at the call site: insertMany(Array.isArray(docs) ? docs : [docs]).","If building the array dynamically, default it: await collection.insertMany(docs ?? []).","Add an Array.isArray(docs) guard before calling insertMany and surface a clearer error to your caller.","Enable strict TypeScript typing on the caller so the non-array value is caught at compile time."],"exampleFix":"// before\nawait collection.insertMany(req.body);\n// after\nawait collection.insertMany(Array.isArray(req.body) ? req.body : [req.body]);","handlingStrategy":"type-guard","validationCode":"function asInsertManyDocs<T>(docs: unknown): T[] {\n  if (!Array.isArray(docs)) {\n    throw new TypeError('insertMany requires an array');\n  }\n  return docs as T[];\n}\n// usage:\nawait collection.insertMany(asInsertManyDocs(maybeDocs));","typeGuard":"const isDocumentArray = (v: unknown): v is Record<string, unknown>[] =>\n  Array.isArray(v) && v.every(d => d != null && typeof d === 'object' && !Array.isArray(d));","tryCatchPattern":"try {\n  await collection.insertMany(docs);\n} catch (e) {\n  if (e instanceof MongoInvalidArgumentError && /must be an array of documents/.test(e.message)) {\n    throw new TypeError('Expected an array of documents, got: ' + typeof docs);\n  }\n  throw e;\n}","preventionTips":["Always type the variable you pass as ReadonlyArray<...>.","Initialize dynamic arrays to [] and push, never assign undefined.","Lint for awaiting promises before passing to insertMany."],"tags":["validation","typescript","crud","insert"],"analyzedSha":"3366c21a6311e02f1be91da982f9b93d3cce99a0","analyzedAt":"2026-08-04T13:40:15.335Z","schemaVersion":2}