{"record":{"id":"d41252660d0850a6","repo":"meteor/meteor","slug":"please-specify-only-one-of-removed-and-removedat","errorCode":null,"errorMessage":"Please specify only one of removed() and removedAt()","messagePattern":"Please specify only one of removed\\(\\) and removedAt\\(\\)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/minimongo/local_collection.js","lineNumber":1695,"sourceCode":"  if (Meteor._isPromise(handle)) {\n    handle.then(setSuppressed);\n  } else {\n    setSuppressed(handle);\n  }\n  return handle;\n};\n\nLocalCollection._observeCallbacksAreOrdered = callbacks => {\n  if (callbacks.added && callbacks.addedAt) {\n    throw new Error('Please specify only one of added() and addedAt()');\n  }\n\n  if (callbacks.changed && callbacks.changedAt) {\n    throw new Error('Please specify only one of changed() and changedAt()');\n  }\n\n  if (callbacks.removed && callbacks.removedAt) {\n    throw new Error('Please specify only one of removed() and removedAt()');\n  }\n\n  return !!(\n    callbacks.addedAt ||\n    callbacks.changedAt ||\n    callbacks.movedTo ||\n    callbacks.removedAt\n  );\n};\n\nLocalCollection._observeChangesCallbacksAreOrdered = callbacks => {\n  if (callbacks.added && callbacks.addedBefore) {\n    throw new Error('Please specify only one of added() and addedBefore()');\n  }\n\n  return !!(callbacks.addedBefore || callbacks.movedBefore);\n};\n","sourceCodeStart":1677,"sourceCodeEnd":1713,"githubUrl":"https://github.com/meteor/meteor/blob/5076d2f818d3cac01d0cf8312fa5b2332076a4fb/packages/minimongo/local_collection.js#L1677-L1713","documentation":"Thrown by LocalCollection._observeCallbacksAreOrdered when both 'removed' (unordered) and 'removedAt' (ordered, with index) are present on the observe callbacks object. Same mutually-exclusive ordered/unordered contract as the added and changed pairs.","triggerScenarios":"Passing cursor.observe({ removed() {...}, removedAt(doc, idx) {...} }) — both keys truthy at observe setup time triggers the synchronous guard.","commonSituations":"Copying a removed handler from an unordered example into an already-ordered observe callbacks object; auto-generating callbacks from a schema where both forms are defined.","solutions":["Pick ordered or unordered and keep only that set of remove callbacks.","Keep removedAt(doc, idx) if you need to know the document's former position; otherwise keep removed(doc).","Audit the callbacks object for all three pairs (added/addedAt, changed/changedAt, removed/removedAt) since the guard runs against each.","Add a unit test asserting no conflicting callback pair is set."],"exampleFix":"// before\nusers.find().observe({ removedAt(doc, idx) {}, removed(doc) {} });\n// after\nusers.find().observe({ removedAt(doc, idx) {} });","handlingStrategy":"validation","validationCode":"function assertNoRemovedPair(cb) {\n  if (cb && cb.removed && cb.removedAt) {\n    throw new TypeError('Choose removed (unordered) OR removedAt (ordered), not both');\n  }\n  return cb;\n}\ncursor.observe(assertNoRemovedPair(callbacks));","typeGuard":"function hasConflictingRemovedPair(cb) {\n  return !!(cb && cb.removed && cb.removedAt);\n}","tryCatchPattern":null,"preventionTips":["Build observe callbacks through one factory so the ordered/unordered choice is made once.","Static-check the callbacks object shape in a unit test.","When merging two callback objects, assert no conflicting pair results."],"tags":["minimongo","observe","ordered","validation","api-misuse"],"backgroundTag":null,"analyzedSha":"5076d2f818d3cac01d0cf8312fa5b2332076a4fb","analyzedAt":"2026-08-13T03:27:40.142Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}