RocketChat/Rocket.Chat · error · Error

error-room-not-served

Error message

error-room-not-served

What it means

Thrown by resumeRoomOnHold when `servedBy` is falsy on the room. The service cannot resume a held chat that has no serving agent to hand it back to; it logs 'No serving agent found for room' at error level before throwing.

Source

Thrown at apps/meteor/ee/server/local-services/omnichannel.internalService.ts:101

		this.logger.debug({ msg: 'Attempting to resume room on hold', roomId: room._id, userId: resumeBy?._id });

		if (!room || !isOmnichannelRoom(room)) {
			throw new Error('error-invalid-room');
		}

		if (!room.open) {
			throw new Error('This_conversation_is_already_closed');
		}

		if (!room.onHold) {
			throw new Error('error-room-not-on-hold');
		}

		const { _id: roomId, servedBy } = room;

		if (!servedBy) {
			this.logger.error({ msg: 'No serving agent found for room', roomId });
			throw new Error('error-room-not-served');
		}

		const inquiry = await LivechatInquiry.findOneByRoomId(roomId, {});
		if (!inquiry) {
			this.logger.error({ msg: 'No inquiry found for room', roomId });
			throw new Error('error-invalid-inquiry');
		}

		await this.attemptToAssignRoomToServingAgentElseQueueIt({
			room,
			inquiry,
			servingAgent: servedBy,
			clientAction,
		});

		const [roomResult, subsResult] = await Promise.all([
			LivechatRooms.unsetOnHoldByRoomId(roomId),
			Subscriptions.unsetOnHoldByRoomId(roomId),

View on GitHub (pinned to f9d3ec372b)

Solutions

  1. Before resume, verify room.servedBy; if missing, route through reassignment/queue rather than resume.
  2. Investigate data integrity if onHold rooms routinely lack servedBy (backfill servedBy or unset onHold).
  3. Surface a clear 'no agent assigned' message in the UI instead of the generic error.

Example fix

// before
await omnichannelService.resumeRoomOnHold(room, comment, user);

// after
if (!room.servedBy) {
  await reassignOrQueueRoom(room);
  return;
}
await omnichannelService.resumeRoomOnHold(room, comment, user);
Defensive patterns

Strategy: validation

Validate before calling

if (!room.servedBy) {
  await reassignOrQueueRoom(room);
  return;
}
await omnichannelService.resumeRoomOnHold(room, comment, user);

Type guard

function hasServerAgent(room: unknown): room is { servedBy: { agentId: string } } {
  return !!room && !!(room as any).servedBy;
}

Try / catch

try {
  await omnichannelService.resumeRoomOnHold(room, comment, user);
} catch (e) {
  if (e instanceof Error && e.message === 'error-room-not-served') {
    await reassignOrQueueRoom(room);
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: Resuming a held room whose servedBy was cleared — e.g. the agent was removed during the hold, the assignment was invalidated, or the room was queued while held.

Common situations: Agent was deleted/deactivated while the chat was held; an admin manually cleared servedBy; data inconsistency where onHold is true but servedBy is missing.

Related errors


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