RocketChat/Rocket.Chat · error · Meteor.Error

error-room-does-not-exist

error-room-does-not-exist

Error message

This room does not exist

What it means

readMessages resolves rid through Rooms.findOneById; when no room document matches (deleted room, wrong or typo'd id, id from a different workspace), it throws error-room-does-not-exist 'This room does not exist'. This is distinct from the following canAccessRoomAsync failure in the same method, which throws error-not-allowed 'Not allowed' instead.

Source

Thrown at apps/meteor/server/meteor-methods/messages/readMessages.ts:31

		readMessages(rid: string, readThreads?: boolean): Promise<void>;
	}
}

Meteor.methods<ServerMethods>({
	async readMessages(rid, readThreads = false) {
		check(rid, String);

		const userId = Meteor.userId();
		if (!userId) {
			throw new Meteor.Error('error-invalid-user', 'Invalid user', {
				method: 'readMessages',
			});
		}

		const user = ((await Meteor.userAsync()) as IUser | null) ?? undefined;
		const room = await Rooms.findOneById(rid);
		if (!room) {
			throw new Meteor.Error('error-room-does-not-exist', 'This room does not exist', { method: 'readMessages' });
		}
		if (!(await canAccessRoomAsync(room, user))) {
			throw new Meteor.Error('error-not-allowed', 'Not allowed', { method: 'readMessages' });
		}

		await readMessages(room, userId, readThreads);
	},
});

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Verify the room exists in the client's Rooms/Subscriptions cache before calling
  2. Invalidate cached room state when the room-removed event arrives
  3. Catch error-room-does-not-exist and silently drop the read request for gone rooms

Example fix

// before
Meteor.call('readMessages', rid);

// after
const room = Rooms.findOne({ _id: rid });
if (!room) {
  // room no longer exists — drop stale state instead of calling
} else {
  Meteor.call('readMessages', rid);
}
Defensive patterns

Strategy: try-catch

Validate before calling

const room = RoomsCollection.findOne({ _id: rid });
if (!room) {
  // room deleted or unknown — drop stale state instead of calling
}

Try / catch

try {
  await Meteor.callAsync('readMessages', rid, readThreads);
} catch (error) {
  if (error instanceof Meteor.Error && error.error === 'error-room-does-not-exist') {
    // room is gone — clear it from local caches silently
  } else {
    throw error;
  }
}

Prevention

When it happens

Trigger: Meteor.call('readMessages', rid) where rid refers to a room that was deleted, a truncated/copy-pasted id, or a rid from stale local state after the room was removed.

Common situations: Mark-as-read effects firing for rooms deleted while the tab was open; deep links with mangled room ids; local caches (IndexedDB, redux persist) holding rids of purged rooms.

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18). Data as JSON: /api/errors/86c15a12d1fb44f1. Report an issue: GitHub.