{"record":{"id":"bbb57d16efc9f931","repo":"RocketChat/Rocket.Chat","slug":"room-not-found-bbb57d","errorCode":null,"errorMessage":"room-not-found","messagePattern":"room-not-found","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/client/lib/getPermaLink.ts","lineNumber":29,"sourceCode":"\t\treturn null;\n\t}\n};\n\nexport const getPermaLink = async (msgId: string): Promise<string> => {\n\tif (!msgId) {\n\t\tthrow new Error('invalid-parameter');\n\t}\n\n\tconst { Messages, Rooms, Subscriptions } = await import('../stores');\n\n\tconst msg = Messages.state.get(msgId) || (await getMessage(msgId));\n\tif (!msg) {\n\t\tthrow new Error('message-not-found');\n\t}\n\tconst roomData = Rooms.state.get(msg.rid);\n\n\tif (!roomData) {\n\t\tthrow new Error('room-not-found');\n\t}\n\n\tconst subData = Subscriptions.state.find((record) => record.rid === roomData._id && record.u._id === getUserId());\n\n\tconst { roomCoordinator } = await import('./rooms/roomCoordinator');\n\n\tconst roomURL = roomCoordinator.getURL(roomData.t, { ...(subData || roomData), tab: '' });\n\treturn `${roomURL}?msg=${msgId}`;\n};\n","sourceCodeStart":11,"sourceCodeEnd":39,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/client/lib/getPermaLink.ts#L11-L39","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nconst link = await getPermaLink(msgId);\n// after\ntry {\n  const link = await getPermaLink(msgId);\n} catch (e) {\n  if (e instanceof Error && e.message === 'room-not-found') {\n    await fetchRoomInfo(msg.rid);\n    return getPermaLink(msgId); // retry\n  }\n  throw e;\n}","handlingStrategy":"retry","validationCode":"const msg = Messages.state.get(msgId);\nif (msg && !Rooms.state.get(msg.rid)) {\n  await fetchRoomInfo(msg.rid); // pre-load room data\n}\nconst link = await getPermaLink(msgId);","typeGuard":"const roomDataAvailable = (rid: string): boolean =>\n  Boolean(Rooms.state.get(rid));","tryCatchPattern":"try {\n  const link = await getPermaLink(msgId);\n} catch (e) {\n  if (e instanceof Error && e.message === 'room-not-found') {\n    await fetchRoomInfo(rid);\n    return getPermaLink(msgId); // retry once\n  }\n  throw e;\n}","preventionTips":["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."],"tags":["permalink","room-not-found","cache","data-hydration","room-data"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}