RocketChat/Rocket.Chat · error · Error
room-not-found
Error message
room-not-found
What it means
Thrown by getPermaLink after successfully finding the message but failing to find its parent room in the local Rooms store (Rooms.state.get(msg.rid)). This means the message was found (either in cache or via API) but the room metadata for the room it belongs to is not loaded in the client. getPermaLink needs room data to construct the room URL via roomCoordinator.
Source
Thrown at apps/meteor/client/lib/getPermaLink.ts:29
return null;
}
};
export const getPermaLink = async (msgId: string): Promise<string> => {
if (!msgId) {
throw new Error('invalid-parameter');
}
const { Messages, Rooms, Subscriptions } = await import('../stores');
const msg = Messages.state.get(msgId) || (await getMessage(msgId));
if (!msg) {
throw new Error('message-not-found');
}
const roomData = Rooms.state.get(msg.rid);
if (!roomData) {
throw new Error('room-not-found');
}
const subData = Subscriptions.state.find((record) => record.rid === roomData._id && record.u._id === getUserId());
const { roomCoordinator } = await import('./rooms/roomCoordinator');
const roomURL = roomCoordinator.getURL(roomData.t, { ...(subData || roomData), tab: '' });
return `${roomURL}?msg=${msgId}`;
};
View on GitHub (pinned to f9d3ec372b)
Solutions
- Fetch the room data from the server before calling getPermaLink, or ensure Rooms store is hydrated.
- Catch the 'room-not-found' error and trigger a room fetch (e.g., /v1/rooms.info), then retry getPermaLink.
- Pre-load room metadata when the user navigates to a permalink from an external source.
- Show a 'room not available' message if the room no longer exists.
Example fix
// before
const link = await getPermaLink(msgId);
// after
try {
const link = await getPermaLink(msgId);
} catch (e) {
if (e instanceof Error && e.message === 'room-not-found') {
await fetchRoomInfo(msg.rid);
return getPermaLink(msgId); // retry
}
throw e;
} Defensive patterns
Strategy: retry
Validate before calling
const msg = Messages.state.get(msgId);
if (msg && !Rooms.state.get(msg.rid)) {
await fetchRoomInfo(msg.rid); // pre-load room data
}
const link = await getPermaLink(msgId); Type guard
const roomDataAvailable = (rid: string): boolean => Boolean(Rooms.state.get(rid));
Try / catch
try {
const link = await getPermaLink(msgId);
} catch (e) {
if (e instanceof Error && e.message === 'room-not-found') {
await fetchRoomInfo(rid);
return getPermaLink(msgId); // retry once
}
throw e;
} Prevention
- Pre-load room metadata when deep-linking from external sources (emails, notifications).
- Ensure the Rooms store is hydrated before calling getPermaLink.
- Catch 'room-not-found' and trigger a room fetch with retry.
When it happens
Trigger: The message is accessible (found via cache or API) but the room metadata is not in the Rooms store. The room was deleted/archived and its metadata removed from the client. The user has access to the message (e.g., via a thread/discussion link) but the room data was not loaded in this session. Store hydration race condition.
Common situations: User clicks a permalink from an email/notification that deep-links to a message in a room they haven't opened this session. Room was archived after the message was sent. Fresh login where rooms haven't fully synced but messages are available via API.
Related errors
AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12).
Data as JSON: /api/errors/bbb57d16efc9f931.
Report an issue: GitHub.