{"record":{"id":"cbabe2f58eb7eb82","repo":"RocketChat/Rocket.Chat","slug":"not-subscribed-room","errorCode":"not-subscribed-room","errorMessage":"Not subscribed to this room","messagePattern":"Not subscribed to this room","errorType":"exception","errorClass":"NotSubscribedToRoomError","httpStatus":null,"severity":"warning","filePath":"apps/meteor/client/views/room/hooks/useOpenRoom.ts","lineNumber":135,"sourceCode":"\n\t\t\tconst room = Rooms.state.get(roomData._id);\n\n\t\t\tif (!room) {\n\t\t\t\tthrow new TypeError('room is undefined');\n\t\t\t}\n\n\t\t\tconst sub = Subscriptions.state.find((record) => record.t === type && (record.rid === reference || record.name === reference));\n\n\t\t\tif (reference !== undefined && room._id !== reference && type === 'd') {\n\t\t\t\t// Redirect old url using username to rid\n\t\t\t\tLegacyRoomManager.close(type + reference);\n\t\t\t\tdirectRoute.push({ rid: room._id }, (prev) => prev);\n\t\t\t\tthrow new OldUrlRoomError(undefined, { rid: room._id });\n\t\t\t}\n\n\t\t\t// if user doesn't exist at this point, anonymous read is enabled, otherwise an error would have been thrown\n\t\t\tif (user && !sub && !hasPreviewPermission && isPublicRoom(room)) {\n\t\t\t\tthrow new NotSubscribedToRoomError(undefined, { rid: room._id });\n\t\t\t}\n\n\t\t\tLegacyRoomManager.open({ typeName: type + reference, rid: room._id });\n\n\t\t\tif (room._id === RoomManager.opened) {\n\t\t\t\treturn { rid: room._id };\n\t\t\t}\n\n\t\t\t// update user's room subscription\n\n\t\t\tif (!!user?._id && sub && !sub.open) {\n\t\t\t\tawait openRoom.mutateAsync({ roomId: room._id, userId: user._id });\n\t\t\t}\n\n\t\t\treturn { rid: room._id };\n\t\t},\n\t\tretry: (failureCount, error) => {\n\t\t\tconst unrecoverableErrors = [RoomNotFoundError, OldUrlRoomError, NotAuthorizedError, NotSubscribedToRoomError];","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/client/views/room/hooks/useOpenRoom.ts#L117-L153","documentation":"Thrown as NotSubscribedToRoomError ('not-subscribed-room') when a logged-in user has no subscription to a public room, lacks the preview-c-room permission, and isPublicRoom(room) is true. It gates access so unsubscribed users cannot read a public room's contents without preview rights.","triggerScenarios":"Authenticated user opens a public channel they never joined, with no preview permission and no subscription record; admin revoked preview-c-room role-wide.","commonSituations":"User follows a link to a public channel they haven't joined; permission role changed to remove preview-c-room; guest user with limited permissions.","solutions":["Grant the user (or their role) the preview-c-room permission if preview is intended.","Offer a join/subscribe action in the resulting no-access UI so the user can opt in.","If access is intentional, subscribe the user to the room."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Check preview permission client-side before relying on the error path.\nconst canPreview = usePermission('preview-c-room');\nif (user && !sub && !canPreview && isPublicRoom(room)) {\n  // show join/subscribe CTA instead of letting the query throw\n}","typeGuard":"const isNotSubscribedError = (e: unknown): boolean => e instanceof NotSubscribedToRoomError;","tryCatchPattern":"if (error instanceof NotSubscribedToRoomError) {\n  return <JoinRoomScreen rid={error.details?.rid} />;\n}","preventionTips":["Grant preview-c-room to roles that should read public rooms without joining.","Offer a subscribe/join action from the not-subscribed screen.","Avoid deep-linking unsubscribed users into public rooms without a join step."],"tags":["client","rooms","permissions","subscriptions"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}