{"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":"error_code","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/2f18297792c973da326be7253f497d239ea6f2b0/apps/meteor/client/views/room/hooks/useOpenRoom.ts#L117-L153","documentation":"NotSubscribedToRoomError (`not-subscribed-room`) thrown by useOpenRoom when the room was resolved, the user is logged in, has no subscription record for it, has no preview permission, and the room is public. It is control flow: react-query consumers catch it to render the room preview screen instead of opening the room.","triggerScenarios":"Logged-in user without membership opening a public channel URL while lacking preview permissions (e.g. uninvited users can't preview); subscription not yet synced to the client after joining elsewhere.","commonSituations":"Clicking a shared public-channel link as a non-member on workspaces that disable previews for users without the preview room permission; race right after join-room where the subscription hasn't propagated.","solutions":["Join the room (POST /v1/channels.join or /v1/groups.join) before opening it.","Grant the user a role with the preview-public-room permission if previewing is intended.","In UI code, catch this error specifically and navigate to the preview route rather than showing a generic error."],"exampleFix":"// before\ntry {\n\tawait openRoom(type, reference);\n} catch (e) {\n\tshowError(e); // generic toast for a control-flow error\n}\n\n// after\ntry {\n\tawait openRoom(type, reference);\n} catch (e) {\n\tif (e instanceof NotSubscribedToRoomError) {\n\t\tpreviewRoute.push({ rid: e.details?.rid });\n\t\treturn;\n\t}\n\tthrow e;\n}","handlingStrategy":"try-catch","validationCode":"const isSubscribed = (type: string, reference: string): boolean =>\n\tBoolean(Subscriptions.state.find((record) => record.t === type && (record.rid === reference || record.name === reference)));","typeGuard":"const isNotSubscribedToRoomError = (error: unknown): error is NotSubscribedToRoomError =>\n\tBoolean(error && typeof error === 'object' && 'error' in error && (error as { error: string }).error === 'not-subscribed-room');","tryCatchPattern":"try {\n\tconst { rid } = await openRoom(type, reference);\n} catch (error) {\n\tif (isNotSubscribedToRoomError(error)) {\n\t\t// control flow: render the public-room preview screen\n\t\tpreviewRoute.push({ rid: error.details?.rid ?? '' });\n\t\treturn;\n\t}\n\tthrow error;\n}","preventionTips":["Treat not-subscribed-room as routing signal, not a bug — never toast it as a generic error.","Join the room (channels.join/groups.join) before deep-linking non-preview users.","Grant preview-public-room permission when uninvited preview is intended."],"tags":["client","subscription","preview","join-room"],"backgroundTag":"subscription-required","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"}