{"record":{"id":"1393f0cc1a7dafd9","repo":"RocketChat/Rocket.Chat","slug":"sla-not-found-with-id-slaid","errorCode":null,"errorMessage":"SLA not found with id: ${slaId}","messagePattern":"SLA not found with id: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/ee/server/hooks/omnichannel/onSaveVisitorInfo.ts","lineNumber":18,"sourceCode":"import type { IOmnichannelRoom, IOmnichannelServiceLevelAgreements, IUser } from '@rocket.chat/core-typings';\nimport { OmnichannelServiceLevelAgreements } from '@rocket.chat/models';\n\nimport { callbacks } from '../../../../server/lib/callbacks';\nimport { removePriorityFromRoom, updateRoomPriority } from '../../api/v1/omnichannel/lib/priorities';\nimport { removeRoomSLA, updateRoomSLA } from '../../api/v1/omnichannel/lib/sla';\n\nconst updateSLA = async (room: IOmnichannelRoom, user: Required<Pick<IUser, '_id' | 'username' | 'name'>>, slaId?: string) => {\n\tif (!slaId) {\n\t\treturn removeRoomSLA(room._id, user);\n\t}\n\n\tconst sla: Pick<IOmnichannelServiceLevelAgreements, '_id' | 'name' | 'dueTimeInMinutes'> | null =\n\t\tawait OmnichannelServiceLevelAgreements.findOneById(slaId, {\n\t\t\tprojection: { _id: 1, name: 1, dueTimeInMinutes: 1 },\n\t\t});\n\tif (!sla) {\n\t\tthrow new Error(`SLA not found with id: ${slaId}`);\n\t}\n\n\tawait updateRoomSLA(room._id, user, sla);\n};\n\nconst updatePriority = async (room: IOmnichannelRoom, user: Required<Pick<IUser, '_id' | 'username' | 'name'>>, priorityId?: string) => {\n\tif (!priorityId) {\n\t\treturn removePriorityFromRoom(room._id, user);\n\t}\n\n\tawait updateRoomPriority(room._id, user, priorityId);\n};\n\ncallbacks.add(\n\t'livechat.saveInfo',\n\tasync (room, { user, oldRoom }: any) => {\n\t\tconst { slaId: oldSlaId, priorityId: oldPriorityId } = oldRoom;\n\t\tconst { slaId: newSlaId, priorityId: newPriorityId } = room;","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/ee/server/hooks/omnichannel/onSaveVisitorInfo.ts#L1-L36","documentation":"Thrown by updateSLA inside the onSaveVisitorInfo omnichannel hook when a non-empty slaId is supplied for a room but no document matches that id in the OmnichannelServiceLevelAgreements collection. It is a plain Error (not Meteor.Error). The SLA is looked up with a projection of _id/name/dueTimeInMinutes; passing an empty/undefined slaId instead routes to removeRoomSLA and never throws.","triggerScenarios":"Visitor info is saved (or room SLA is set) with an slaId referencing a deleted or never-created SLA record; a stale slaId is sent from a client after an admin removed the SLA; an integration passes a typo'd id.","commonSituations":"SLA was deleted between the time the client loaded the dropdown and the time the form was submitted; import/migration left rooms pointing at SLA ids that were not migrated; concurrent admin deletion.","solutions":["Verify the slaId still exists in OmnichannelServiceLevelAgreements before retrying (db query or the SLA list API).","Re-fetch the available SLAs on the client and re-submit with a valid id, or send an empty slaId to clear it.","Audit recently deleted SLAs and clean up references on rooms that still point to them."],"exampleFix":"// before: blindly forward a stale id\nawait updateSLA(room, user, possiblyStaleSlaId);\n\n// after: confirm existence first\nconst sla = await OmnichannelServiceLevelAgreements.findOneById(slaId);\nif (!sla) {\n  // surface 'SLA not found' to user / pick a valid SLA instead\n  return removeRoomSLA(room._id, user);\n}\nawait updateRoomSLA(room._id, user, sla);","handlingStrategy":"validation","validationCode":"async function safeUpdateSLA(room, user, slaId?: string) {\n  if (!slaId) return removeRoomSLA(room._id, user);\n  const sla = await OmnichannelServiceLevelAgreements.findOneById(slaId, { projection: { _id: 1, name: 1, dueTimeInMinutes: 1 } });\n  if (!sla) throw new Error(`SLA not found with id: ${slaId}`);\n  return updateRoomSLA(room._id, user, sla);\n}","typeGuard":"const isSlaRef = (id: unknown): id is string => typeof id === 'string' && id.trim().length > 0;","tryCatchPattern":"try { await onSaveVisitorInfo(...); } catch (e) {\n  if (e instanceof Error && e.message.startsWith('SLA not found with id')) {\n    // refresh SLA list on client, clear or repick slaId\n  } else throw e;\n}","preventionTips":["Re-fetch SLA options right before submitting visitor info edits.","Run a cleanup job that clears room.slaId when the SLA document is deleted.","Pass undefined (not a stale id) when the user clears the SLA field."],"tags":["omnichannel","sla","data-integrity","enterprise"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}