{"id":"d5de58c55ba9e53a","repo":"mongodb/node-mongodb-native","slug":"document-must-be-a-valid-javascript-object","errorCode":null,"errorMessage":"Document must be a valid JavaScript object","messagePattern":"Document must be a valid JavaScript object","errorType":"exception","errorClass":"MongoInvalidArgumentError","httpStatus":null,"severity":"error","filePath":"src/operations/update.ts","lineNumber":270,"sourceCode":"      upsertedId:\n        Array.isArray(res.upserted) && res.upserted.length > 0 ? res.upserted[0]._id : null,\n      upsertedCount: Array.isArray(res.upserted) && res.upserted.length ? res.upserted.length : 0,\n      matchedCount: Array.isArray(res.upserted) && res.upserted.length > 0 ? 0 : res.n\n    };\n  }\n}\n\nexport function makeUpdateStatement(\n  filter: Document,\n  update: Document | Document[],\n  options: UpdateOptions & { multi?: boolean } & { sort?: Sort }\n): UpdateStatement {\n  if (filter == null || typeof filter !== 'object') {\n    throw new MongoInvalidArgumentError('Selector must be a valid JavaScript object');\n  }\n\n  if (update == null || typeof update !== 'object') {\n    throw new MongoInvalidArgumentError('Document must be a valid JavaScript object');\n  }\n\n  const op: UpdateStatement = { q: filter, u: update };\n  if (typeof options.upsert === 'boolean') {\n    op.upsert = options.upsert;\n  }\n\n  if (options.multi) {\n    op.multi = options.multi;\n  }\n\n  if (options.hint) {\n    op.hint = options.hint;\n  }\n\n  if (options.arrayFilters) {\n    op.arrayFilters = options.arrayFilters;\n  }","sourceCodeStart":252,"sourceCodeEnd":288,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/3366c21a6311e02f1be91da982f9b93d3cce99a0/src/operations/update.ts#L252-L288","documentation":"Thrown by makeUpdateStatement when the update/replacement document passed to update/updateOne/updateMany/replaceOne/findOneAnd* is null or not an object. The mutation argument must be a JavaScript object (or array pipeline for updates). A null/undefined/primitive triggers this MongoInvalidArgumentError before any wire request.","triggerScenarios":"collection.updateOne(filter, null) or updateOne(filter, undefined) because the update was constructed conditionally and ended up unset; passing a primitive where the update document belongs; a function returning undefined used as the update argument.","commonSituations":"Conditionally built update objects where a branch returns nothing; bad destructuring; refactoring that moved update construction out of a helper which can now return undefined; passing the wrong variable.","solutions":["Ensure the update argument is always an object: default it, or skip the write entirely when there is nothing to update.","For updateOne/updateMany include atomic operators; for replaceOne include a plain document.","Add a guard that skips the call when the constructed update is null/undefined.","Check the return of helper functions that build update documents."],"exampleFix":"// before\nawait collection.updateOne(filter, buildUpdate(data)); // buildUpdate returned undefined\n// after\nconst update = buildUpdate(data);\nif (update) await collection.updateOne(filter, update);","handlingStrategy":"type-guard","validationCode":"function isDocObject(d) {\n  return d != null && typeof d === 'object';\n}\nif (!isDocObject(update)) throw new Error('update must be a non-null object');\nawait collection.updateOne(filter, update);","typeGuard":"function isDocObject(d: unknown): d is Record<string, unknown> {\n  return d != null && typeof d === 'object';\n}","tryCatchPattern":null,"preventionTips":["Skip writes when a conditionally-built update is null/undefined.","Type helper functions' return values that produce update documents.","Guard against helpers returning undefined on edge-case inputs."],"tags":["update","validation","argument-error"],"analyzedSha":"3366c21a6311e02f1be91da982f9b93d3cce99a0","analyzedAt":"2026-08-04T13:40:15.335Z","schemaVersion":2}