RocketChat/Rocket.Chat · error · Error
Subscription not found
Error message
Subscription not found
What it means
Thrown via createStrictGetter, a generic wrapper that calls findSubscription and throws if the result is falsy. findSubscription searches the Subscriptions store for a record whose rid matches the chat context's room ID. If the user has no subscription for this room (meaning they are not a member), the strict getter throws 'Subscription not found'.
Source
Thrown at apps/meteor/client/lib/chats/data.ts:301
const getDiscussionByID = async (drid: IRoom['_id']): Promise<IRoom> => {
const discussion = await findDiscussionByID(drid);
if (!discussion) {
throw new Error('Discussion not found');
}
return discussion;
};
const createStrictGetter = <TFind extends (...args: any[]) => Promise<any>>(
find: TFind,
errorMessage: string,
): ((...args: Parameters<TFind>) => Promise<Exclude<Awaited<ReturnType<TFind>>, undefined>>) => {
return async (...args) => {
const result = await find(...args);
if (!result) {
throw new Error(errorMessage);
}
return result;
};
};
const findSubscription = async (): Promise<ISubscription | undefined> => {
return Subscriptions.state.find((record) => record.rid === rid);
};
const getSubscription = createStrictGetter(findSubscription, 'Subscription not found');
const findSubscriptionFromMessage = async (message: IMessage): Promise<ISubscription | undefined> => {
return Subscriptions.state.find((record) => record.rid === message.rid);
};
const getSubscriptionFromMessage = createStrictGetter(findSubscriptionFromMessage, 'Subscription not found');
View on GitHub (pinned to f9d3ec372b)
Solutions
- Switch to findSubscription() which returns undefined instead of throwing, and handle non-membership gracefully.
- Call joinRoom() before getSubscription() to ensure the user is subscribed.
- Check isSubscribedToRoom() (the boolean guard) before calling getSubscription.
- Catch the error and show a join-room prompt or redirect the user.
Example fix
// before
const sub = await getSubscription();
// after
if (!(await isSubscribedToRoom())) {
await joinRoom();
}
const sub = await getSubscription(); Defensive patterns
Strategy: validation
Validate before calling
if (!(await isSubscribedToRoom())) {
await joinRoom();
}
const sub = await getSubscription(); Type guard
const isSubscribed = async (): Promise<boolean> => {
return Boolean(await findSubscription());
}; Try / catch
try {
const sub = await getSubscription();
} catch (e) {
if (e instanceof Error && e.message === 'Subscription not found') {
// prompt user to join the room
showJoinPrompt();
return;
}
throw e;
} Prevention
- Call isSubscribedToRoom() or use findSubscription() before the strict getter.
- Join the room (joinRoom()) before accessing subscription data.
- Wait for the subscriptions sync to complete after login before accessing subscription data.
When it happens
Trigger: The current user is not subscribed to the room (not a member). The Subscriptions store has not finished syncing after login. The subscription was removed (user left/was removed from the room) but the component is still mounted. Accessing a room via a permalink without having joined it.
Common situations: Previewing a public room before joining. User was kicked/removed from a room but the UI hasn't updated. Fresh login where the subscriptions sync is still in progress. Direct link to a room the user has never joined.
Related errors
AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12).
Data as JSON: /api/errors/b7d5fd768387d855.
Report an issue: GitHub.