{"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/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/ee/server/hooks/omnichannel/onSaveVisitorInfo.ts#L1-L36","documentation":"Plain Error thrown by updateSLA in the visitor-info save hook when the incoming visitor data carries an slaId but OmnichannelServiceLevelAgreements.findOneById(slaId) finds no SLA. The hook must convert the id into a full SLA record (name + dueTimeInMinutes) to update the room, so a dangling slaId aborts the visitor-info save with 'SLA not found with id: <id>'.","triggerScenarios":"Updating livechat visitor info (e.g. via the visitor API or contact management) with slaId from a deleted SLA; frontend holding a stale SLA selection; SLA purged during data cleanup while rooms/visitors still reference it.","commonSituations":"SLAs deleted after being assigned to visitors; environment syncs that drop SLA collections; integrations POSTing visitor fields including an old slaId.","solutions":["Remove the stale slaId from the visitor-info payload (omit the field, or pass the new SLA's id)","Recreate an SLA with the referenced id if the reference must stay valid","Audit rooms/visitors for dangling slaId references after deleting SLAs"],"exampleFix":"// before: saving visitor info with a possibly-dangling slaId\nawait saveVisitorInfo(visitorId, { ...info, slaId });\n\n// after: validate the reference, or clear it, before saving\nconst sla = slaId\n  ? await OmnichannelServiceLevelAgreements.findOneById(slaId, { projection: { _id: 1 } })\n  : null;\nif (slaId && !sla) {\n  delete info.slaId; // or reassign to a current SLA id\n}\nawait saveVisitorInfo(visitorId, { ...info, slaId });","handlingStrategy":"validation","validationCode":"const slaIdIsLive = async (slaId?: string): Promise<boolean> =>\n  !slaId || Boolean(await OmnichannelServiceLevelAgreements.findOneById(slaId, { projection: { _id: 1 } }));","typeGuard":null,"tryCatchPattern":"try {\n  await saveVisitorInfo(visitorId, info);\n} catch (err: any) {\n  if (err?.message?.startsWith('SLA not found with id:')) {\n    // strip the stale slaId from the payload and save again\n  }\n  throw err;\n}","preventionTips":["When deleting an SLA, clear slaId from visitor records and widget configs that reference it","Treat slaId as a foreign key: validate on write in integration code","Keep SLA ids stable across environment syncs"],"tags":["omnichannel","livechat","sla","dangling-reference"],"backgroundTag":"sla-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"}