{"id":"17720124aff6b438","repo":"mongodb/node-mongodb-native","slug":"selector-must-be-a-valid-javascript-object","errorCode":null,"errorMessage":"Selector must be a valid JavaScript object","messagePattern":"Selector must be a valid JavaScript object","errorType":"exception","errorClass":"MongoInvalidArgumentError","httpStatus":null,"severity":"error","filePath":"src/operations/update.ts","lineNumber":266,"sourceCode":"\n    return {\n      acknowledged: this.writeConcern?.w !== 0,\n      modifiedCount: res.nModified ?? res.n,\n      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  }","sourceCodeStart":248,"sourceCodeEnd":284,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/3366c21a6311e02f1be91da982f9b93d3cce99a0/src/operations/update.ts#L248-L284","documentation":"Thrown by makeUpdateStatement when the filter (selector) passed to update/updateOne/updateMany/replaceOne/findOneAnd* is null or not an object. The filter must be a JavaScript object (including {} for 'all'). Passing null, undefined, a string, number, or array triggers this MongoInvalidArgumentError client-side.","triggerScenarios":"Calling collection.updateOne(null, ...) or updateOne(undefined, ...) because a variable holding the filter was not initialized; passing a primitive id directly (updateOne(5, ...)) instead of { _id: 5 }; passing an array where a filter object is expected.","commonSituations":"Uninitialized filter variables; refactoring that left a filter unset on some path; assuming an _id can be passed bare (it cannot - wrap in { _id: ... }); destructuring bugs producing undefined.","solutions":["Pass a filter object, using {} to match all documents.","Wrap ids: { _id: value } rather than the bare value.","Default uninitialized filter variables to {} or validate they are objects before calling.","If the filter is genuinely unknown, decide explicitly between {} (all) or no operation."],"exampleFix":"// before\nawait collection.updateOne(maybeFilter, { $set: { x: 1 } }); // maybeFilter is undefined\n// after\nawait collection.updateOne(maybeFilter ?? {}, { $set: { x: 1 } });","handlingStrategy":"type-guard","validationCode":"function isFilterObject(f) {\n  return f != null && typeof f === 'object' && !Array.isArray(f);\n}\nif (!isFilterObject(filter)) throw new Error('filter must be a plain object (use {} for all)');\nawait collection.updateOne(filter, update);","typeGuard":"function isFilterObject(f: unknown): f is Record<string, unknown> {\n  return f != null && typeof f === 'object' && !Array.isArray(f);\n}","tryCatchPattern":null,"preventionTips":["Default filter variables to {} when they may be unset.","Wrap ids as { _id: value }, never bare.","Validate filters at the boundary of dynamic/config-driven code."],"tags":["update","filter","validation","argument-error"],"analyzedSha":"3366c21a6311e02f1be91da982f9b93d3cce99a0","analyzedAt":"2026-08-04T13:40:15.335Z","schemaVersion":2}