RocketChat/Rocket.Chat · error · Error

SLA not found with id: ${slaId}

Error message

SLA not found with id: ${slaId}

What it means

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.

Source

Thrown at apps/meteor/ee/server/hooks/omnichannel/onSaveVisitorInfo.ts:18

import type { IOmnichannelRoom, IOmnichannelServiceLevelAgreements, IUser } from '@rocket.chat/core-typings';
import { OmnichannelServiceLevelAgreements } from '@rocket.chat/models';

import { callbacks } from '../../../../server/lib/callbacks';
import { removePriorityFromRoom, updateRoomPriority } from '../../api/v1/omnichannel/lib/priorities';
import { removeRoomSLA, updateRoomSLA } from '../../api/v1/omnichannel/lib/sla';

const updateSLA = async (room: IOmnichannelRoom, user: Required<Pick<IUser, '_id' | 'username' | 'name'>>, slaId?: string) => {
	if (!slaId) {
		return removeRoomSLA(room._id, user);
	}

	const sla: Pick<IOmnichannelServiceLevelAgreements, '_id' | 'name' | 'dueTimeInMinutes'> | null =
		await OmnichannelServiceLevelAgreements.findOneById(slaId, {
			projection: { _id: 1, name: 1, dueTimeInMinutes: 1 },
		});
	if (!sla) {
		throw new Error(`SLA not found with id: ${slaId}`);
	}

	await updateRoomSLA(room._id, user, sla);
};

const updatePriority = async (room: IOmnichannelRoom, user: Required<Pick<IUser, '_id' | 'username' | 'name'>>, priorityId?: string) => {
	if (!priorityId) {
		return removePriorityFromRoom(room._id, user);
	}

	await updateRoomPriority(room._id, user, priorityId);
};

callbacks.add(
	'livechat.saveInfo',
	async (room, { user, oldRoom }: any) => {
		const { slaId: oldSlaId, priorityId: oldPriorityId } = oldRoom;
		const { slaId: newSlaId, priorityId: newPriorityId } = room;

View on GitHub (pinned to f9d3ec372b)

Solutions

  1. Verify the slaId still exists in OmnichannelServiceLevelAgreements before retrying (db query or the SLA list API).
  2. Re-fetch the available SLAs on the client and re-submit with a valid id, or send an empty slaId to clear it.
  3. Audit recently deleted SLAs and clean up references on rooms that still point to them.

Example fix

// before: blindly forward a stale id
await updateSLA(room, user, possiblyStaleSlaId);

// after: confirm existence first
const sla = await OmnichannelServiceLevelAgreements.findOneById(slaId);
if (!sla) {
  // surface 'SLA not found' to user / pick a valid SLA instead
  return removeRoomSLA(room._id, user);
}
await updateRoomSLA(room._id, user, sla);
Defensive patterns

Strategy: validation

Validate before calling

async function safeUpdateSLA(room, user, slaId?: string) {
  if (!slaId) return removeRoomSLA(room._id, user);
  const sla = await OmnichannelServiceLevelAgreements.findOneById(slaId, { projection: { _id: 1, name: 1, dueTimeInMinutes: 1 } });
  if (!sla) throw new Error(`SLA not found with id: ${slaId}`);
  return updateRoomSLA(room._id, user, sla);
}

Type guard

const isSlaRef = (id: unknown): id is string => typeof id === 'string' && id.trim().length > 0;

Try / catch

try { await onSaveVisitorInfo(...); } catch (e) {
  if (e instanceof Error && e.message.startsWith('SLA not found with id')) {
    // refresh SLA list on client, clear or repick slaId
  } else throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12). Data as JSON: /api/errors/1393f0cc1a7dafd9. Report an issue: GitHub.