{"record":{"id":"25e317b901d4e30f","repo":"RocketChat/Rocket.Chat","slug":"error-unit-not-found","errorCode":"error-unit-not-found","errorMessage":"Unit not found","messagePattern":"Unit not found","errorType":"error_code","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/ee/server/lib/omnichannel/LivechatEnterprise.ts","lineNumber":111,"sourceCode":"\n\t\tcheck(unitDepartments, [\n\t\t\tMatch.ObjectIncluding({\n\t\t\t\tdepartmentId: String,\n\t\t\t}),\n\t\t]);\n\n\t\tlet ancestors: string[] = [];\n\t\tif (_id) {\n\t\t\tconst unitsFromUser = await getUnitsFromUser(userId);\n\t\t\tconst unit = await LivechatUnit.findOneById<Pick<IOmnichannelBusinessUnit, '_id' | 'ancestors'>>(\n\t\t\t\t_id,\n\t\t\t\t{\n\t\t\t\t\tprojection: { _id: 1, ancestors: 1 },\n\t\t\t\t},\n\t\t\t\t{ unitsFromUser },\n\t\t\t);\n\t\t\tif (!unit) {\n\t\t\t\tthrow new Meteor.Error('error-unit-not-found', 'Unit not found', {\n\t\t\t\t\tmethod: 'livechat:saveUnit',\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tancestors = unit.ancestors || [];\n\t\t}\n\n\t\tconst validUserMonitors = await Users.findUsersInRolesWithQuery(\n\t\t\t'livechat-monitor',\n\t\t\t{ _id: { $in: unitMonitors.map(({ monitorId }) => monitorId) } },\n\t\t\t{ projection: { _id: 1, username: 1 } },\n\t\t).toArray();\n\n\t\tconst monitors = validUserMonitors.map(({ _id: monitorId, username }) => ({\n\t\t\tmonitorId,\n\t\t\tusername: username!,\n\t\t}));\n","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/ee/server/lib/omnichannel/LivechatEnterprise.ts#L93-L129","documentation":"saveUnit, when updating (non-null _id), loads the unit with findOneById scoped by the caller's allowed units to read its ancestors. If no unit matches, it throws error-unit-not-found for method livechat:saveUnit.","triggerScenarios":"Saving an edit to a unit whose id no longer exists or is outside the caller's unit scope (getUnitsFromUser).","commonSituations":"Editing a unit deleted in another session; stale form after unit re-organization; unit-scoped admin editing an out-of-scope unit.","solutions":["Reload the unit from the server before saving and confirm it still exists","Ensure the saving user has access to the unit, or save from an unrestricted admin","If the unit was deleted, create it anew instead of saving the stale id"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const unit = _id && (await LivechatUnit.findOneById(_id, { projection: { _id: 1 } }));\nif (_id && !unit) {\n\t// unit no longer editable: reload the form or create a new unit\n}\nawait LivechatEnterprise.saveUnit(_id, unitData, unitMonitors, unitDepartments, userId);","typeGuard":null,"tryCatchPattern":"try {\n\tawait LivechatEnterprise.saveUnit(_id, unitData, unitMonitors, unitDepartments, userId);\n} catch (err) {\n\tif ((err as Meteor.Error)?.error === 'error-unit-not-found') {\n\t\t// reload units; save only when the target still exists in the caller's scope\n\t} else {\n\t\tthrow err;\n\t}\n}","preventionTips":["Reload the entity immediately before saving edits","Keep edit forms short-lived so stale ids are rare","Ensure the saving user's unit scope includes the edited unit"],"tags":["omnichannel","business-unit","not-found"],"backgroundTag":"resource-not-found","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}