{"record":{"id":"6a8d439dff171ed7","repo":"RocketChat/Rocket.Chat","slug":"error-creating-updating-unit","errorCode":null,"errorMessage":"Error creating/updating unit","messagePattern":"Error creating/updating unit","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/ee/server/models/raw/LivechatUnit.ts","lineNumber":77,"sourceCode":"\t\tmonitors = ([] as { monitorId: string; username: string }[]).concat(monitors || []);\n\t\tancestors = ([] as string[]).concat(ancestors || []);\n\n\t\tconst record = {\n\t\t\tname,\n\t\t\tvisibility,\n\t\t\ttype: 'u',\n\t\t\tnumMonitors: monitors.length,\n\t\t\tnumDepartments: departments.length,\n\t\t};\n\n\t\tif (_id) {\n\t\t\tawait this.updateOne({ _id }, { $set: record });\n\t\t} else {\n\t\t\t_id = (await this.insertOne(record)).insertedId;\n\t\t}\n\n\t\tif (!_id) {\n\t\t\tthrow new Error('Error creating/updating unit');\n\t\t}\n\n\t\tancestors.splice(0, 0, _id);\n\n\t\tconst savedMonitors = (await LivechatUnitMonitors.findByUnitId(_id).toArray()).map(({ monitorId }) => monitorId);\n\t\tconst monitorsToSave = monitors.map(({ monitorId }) => monitorId);\n\n\t\t// remove other monitors\n\t\tfor await (const monitorId of savedMonitors) {\n\t\t\tif (!monitorsToSave.includes(monitorId)) {\n\t\t\t\tawait LivechatUnitMonitors.removeByUnitIdAndMonitorId(_id, monitorId);\n\t\t\t}\n\t\t}\n\n\t\tfor await (const monitor of monitors) {\n\t\t\tawait LivechatUnitMonitors.saveMonitor({\n\t\t\t\tmonitorId: monitor.monitorId,\n\t\t\t\tunitId: _id,","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/ee/server/models/raw/LivechatUnit.ts#L59-L95","documentation":"Thrown by LivechatUnitRaw.createOrUpdateUnit after either an insert or an update when _id is still falsy. Because updateOne does not return a new id and insertOne is expected to populate insertedId, a falsy _id here means the MongoDB write did not produce an identifier — an exceptional, low-level persistence failure. It is a plain Error (not a Meteor.Error) since it is raised inside a model/raw layer.","triggerScenarios":"insertOne resolves but insertedId is undefined (driver bug, interrupted connection, or the collection is a view/invalid); updateOne was called with an _id that did not match any document and the code path kept _id as the original null; MongoDB reject due to duplicate key or write-concern timeout that did not throw earlier.","commonSituations":"Network blip / replica-set failover between the write and the driver ack; passing _id as an empty string instead of null when you want a create; sharded cluster where the insert returned no insertedId; schema/validation rule on the livechat_department collection that silently rejects the document.","solutions":["Check MongoDB server logs and the Rocket.Chat mongo connection for the failing write.","Ensure createOrUpdateUnit is called with _id === null (not '' or undefined) for creates and a real ObjectId/string for updates.","Confirm the livechat_department collection is a real collection, not a view, and has no conflicting JSON Schema validator.","Retry the unit create/update after confirming connectivity; if it persists, inspect the WriteError/duplicate key."],"exampleFix":"// before\nawait LivechatUnit.createOrUpdateUnit('', { name, visibility }, ancestors, monitors, departments);\n\n// after\nawait LivechatUnit.createOrUpdateUnit(null, { name, visibility }, ancestors, monitors, departments);","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await LivechatUnit.createOrUpdateUnit(unitId, { name, visibility }, ancestors, monitors, departments);\n} catch (e) {\n  if (e.message === 'Error creating/updating unit') {\n    // inspect Mongo connection / server logs, then retry once with a clean session\n  } else throw e;\n}","preventionTips":["Pass _id === null for creates and a real id for updates — never an empty string.","Monitor MongoDB connectivity and replica-set health.","Ensure the livechat_department collection has no conflicting validator.","Log insertedId after insertOne in tests to catch driver regressions."],"tags":["omnichannel","unit","mongodb","persistence","data-integrity"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}