{"record":{"id":"5e9366e1f8921ff8","repo":"RocketChat/Rocket.Chat","slug":"room-not-found","errorCode":null,"errorMessage":"Room not found","messagePattern":"Room not found","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/client/lib/chats/data.ts","lineNumber":268,"sourceCode":"\tconst drafts = new Map<IMessage['_id'] | undefined, string>();\n\n\tconst getDraft = async (mid: IMessage['_id'] | undefined): Promise<string | undefined> => drafts.get(mid);\n\n\tconst discardDraft = async (mid: IMessage['_id'] | undefined): Promise<void> => {\n\t\tdrafts.delete(mid);\n\t};\n\n\tconst saveDraft = async (mid: IMessage['_id'] | undefined, draft: string): Promise<void> => {\n\t\tdrafts.set(mid, draft);\n\t};\n\n\tconst findRoom = async (): Promise<IRoom | undefined> => Rooms.state.get(rid);\n\n\tconst getRoom = async (): Promise<IRoom> => {\n\t\tconst room = await findRoom();\n\n\t\tif (!room) {\n\t\t\tthrow new Error('Room not found');\n\t\t}\n\n\t\treturn room;\n\t};\n\n\tconst isSubscribedToRoom = async (): Promise<boolean> => !!Subscriptions.state.find((record) => record.rid === rid);\n\n\tconst joinRoom = async (): Promise<void> => {\n\t\tawait sdk.rest.post('/v1/rooms.join', { roomId: rid });\n\t};\n\n\tconst findDiscussionByID = async (drid: IRoom['_id']): Promise<IRoom | undefined> =>\n\t\tRooms.state.find((record) => Boolean(record._id === drid && record.prid));\n\n\tconst getDiscussionByID = async (drid: IRoom['_id']): Promise<IRoom> => {\n\t\tconst discussion = await findDiscussionByID(drid);\n\n\t\tif (!discussion) {","sourceCodeStart":250,"sourceCodeEnd":286,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/2f18297792c973da326be7253f497d239ea6f2b0/apps/meteor/client/lib/chats/data.ts#L250-L286","documentation":"getRoom() throws 'Room not found' when Rooms.state.get(rid) returns undefined — the room record is not present in the local reactive Rooms store. Like the other strict getters in this factory it has no server fallback; it only reflects the client's synced room cache.","triggerScenarios":"Calling getRoom before the user's rooms/subscriptions have finished syncing on login, with a mistyped or foreign rid, or for a room the client never loaded (e.g. referenced only through a message from another context).","commonSituations":"Deep-linking straight into a room URL before the initial subscription load completes; handling a notification for a room the client has not subscribed to; rid taken from a message of a public room the user never opened.","solutions":["Use findRoom and handle undefined (show loading until rooms sync).","Verify the rid source (route param, notification payload) and that the room exists on the server via /v1/rooms.info.","Await the initial rooms/subscriptions load before invoking strict getters."],"exampleFix":"// before\nconst room = await chat.getRoom();\n\n// after\nconst room = await chat.findRoom();\nif (!room) {\n  // rooms still syncing or rid invalid\n  return;\n}","handlingStrategy":"validation","validationCode":"const room = await chat.findRoom();\nif (!room) {\n  // rooms still syncing or rid invalid — show loading / bail\n  return;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Await the initial rooms/subscriptions sync before strict room getters.","Validate rid sources (routes, notifications) against the server when in doubt.","Use findRoom in UI paths; keep getRoom for guaranteed-loaded contexts."],"tags":["rooms","cache","subscriptions"],"backgroundTag":"room-not-found","analyzedSha":"2f18297792c973da326be7253f497d239ea6f2b0","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}