{"record":{"id":"61591f1f1e4f5df4","repo":"Automattic/mongoose","slug":"cannot-pass-an-array-to-query-updates-unless-the","errorCode":null,"errorMessage":"Cannot pass an array to query updates unless the `updatePipeline` option is set.","messagePattern":"Cannot pass an array to query updates unless the `updatePipeline` option is set\\.","errorType":"exception","errorClass":"MongooseError","httpStatus":null,"severity":"error","filePath":"lib/query.js","lineNumber":3540,"sourceCode":"  }\n\n  const globalReturnDocument = this?.model?.base?.options?.returnDocument;\n  const globalReturnOriginal = this?.model?.base?.options?.returnOriginal;\n  if (options.new == null && options.returnDocument == null && options.returnOriginal == null) {\n    if (globalReturnDocument != null) {\n      options.returnDocument = globalReturnDocument;\n    } else if (globalReturnOriginal != null) {\n      options.returnOriginal = globalReturnOriginal;\n    }\n  }\n\n  const updatePipeline = this?.model?.base?.options?.updatePipeline;\n  if (options.updatePipeline == null && updatePipeline != null) {\n    options.updatePipeline = updatePipeline;\n  }\n\n  if (!options.updatePipeline && Array.isArray(update)) {\n    throw new MongooseError('Cannot pass an array to query updates unless the `updatePipeline` option is set.');\n  }\n\n  this.setOptions(options);\n\n  // apply doc\n  if (update) {\n    if (this[queryUpdateSymbol] == null || utils.isEmptyObject(this[queryUpdateSymbol])) {\n      this[queryUpdateSymbol] = update;\n      this._updateIsShared = true;\n    } else {\n      this._mergeUpdate(update);\n    }\n  }\n\n  return this;\n};\n\n/**","sourceCodeStart":3522,"sourceCodeEnd":3558,"githubUrl":"https://github.com/Automattic/mongoose/blob/49cdab01366679723b487ecb754b38570f783289/lib/query.js#L3522-L3558","documentation":"findOneAndUpdate treats an array in the update slot as an aggregation pipeline only when the updatePipeline option is enabled — per call via { updatePipeline: true } or globally via mongoose.set('updatePipeline', true). Without the flag, an array update throws immediately because classic update documents must be plain objects; this differs from the raw MongoDB driver, where array updates are always pipelines.","triggerScenarios":".findOneAndUpdate({ _id }, [{ $set: { count: { $add: ['$count', 1] } } }]) with no options; copying native-driver pipeline updates into Mongoose; using pipeline-only operators ($add, $cond, $subtract) inside $set.","commonSituations":"Atomic math beyond $inc (e.g. multiply two fields, conditional updates); migrating from the MongoDB node driver; tutorials written against driver syntax.","solutions":["Pass the option: .findOneAndUpdate(filter, pipeline, { updatePipeline: true, returnDocument: 'after' })","Or enable it globally with mongoose.set('updatePipeline', true) if most updates are pipelines","If no pipeline operators are needed, use a classic object update instead: { $inc: { count: 1 } }"],"exampleFix":"// before\nconst doc = await Model.findOneAndUpdate(\n  { _id },\n  [{ $set: { count: { $add: ['$count', 1] } } }]\n);\n\n// after\nconst doc = await Model.findOneAndUpdate(\n  { _id },\n  [{ $set: { count: { $add: ['$count', 1] } } }],\n  { updatePipeline: true, returnDocument: 'after' }\n);","handlingStrategy":"validation","validationCode":"// Infer the flag so array updates always carry updatePipeline\nconst opts = { ...baseOptions, ...(Array.isArray(update) ? { updatePipeline: true } : null) };\nconst doc = await Model.findOneAndUpdate(filter, update, opts);","typeGuard":"const isPipelineUpdate = (u) => Array.isArray(u);","tryCatchPattern":null,"preventionTips":["Always set updatePipeline when the update is an aggregation array","Wrap update helpers in a small adapter that infers the flag automatically","Use classic { $inc, $set } object updates when pipeline operators aren't needed"],"tags":["mongoose","query","findoneandupdate","aggregation-pipeline","update","options"],"backgroundTag":"update-pipeline-option-required","analyzedSha":"49cdab01366679723b487ecb754b38570f783289","analyzedAt":"2026-08-21T22:54:00.882Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}