{"record":{"id":"23447221f8a1e2b6","repo":"RocketChat/Rocket.Chat","slug":"error-subscription-not-found-234472","errorCode":"error-subscription-not-found","errorMessage":"Subscription not found","messagePattern":"Subscription not found","errorType":"error_code","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/lib/messaging/unread/unreadMessages.ts","lineNumber":63,"sourceCode":"\t\t});\n\t}\n\n\tconst originalMessage = await Messages.findOneById(firstUnreadMessage._id, {\n\t\tprojection: {\n\t\t\tu: 1,\n\t\t\trid: 1,\n\t\t\tts: 1,\n\t\t},\n\t});\n\tif (!originalMessage || userId === originalMessage.u._id) {\n\t\tthrow new Meteor.Error('error-action-not-allowed', 'Not allowed', {\n\t\t\tmethod: 'unreadMessages',\n\t\t\taction: 'Unread_messages',\n\t\t});\n\t}\n\tconst lastSeen = (await Subscriptions.findOneByRoomIdAndUserId(originalMessage.rid, userId))?.ls;\n\tif (!lastSeen) {\n\t\tthrow new Meteor.Error('error-subscription-not-found', 'Subscription not found', {\n\t\t\tmethod: 'unreadMessages',\n\t\t\taction: 'Unread_messages',\n\t\t});\n\t}\n\n\tif (originalMessage.ts >= lastSeen) {\n\t\treturn logger.debug('Provided message is already marked as unread');\n\t}\n\n\tlogger.debug({\n\t\tmsg: 'Updating unread message as the first unread',\n\t\ttimestamp: originalMessage.ts,\n\t});\n\tconst setAsUnreadResponse = await Subscriptions.setAsUnreadByRoomIdAndUserId(originalMessage.rid, userId, originalMessage.ts);\n\tif (setAsUnreadResponse.modifiedCount) {\n\t\tvoid notifyOnSubscriptionChangedByRoomIdAndUserId(originalMessage.rid, userId);\n\t}\n};","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/lib/messaging/unread/unreadMessages.ts#L45-L81","documentation":"unreadMessages requires the caller to have a subscription with a last-seen timestamp in the message's room: Subscriptions.findOneByRoomIdAndUserId(rid, userId)?.ls. A missing subscription (or one without ls) throws Meteor.Error('error-subscription-not-found', 'Subscription not found') - without ls the server cannot compute the unread window.","triggerScenarios":"Marking a message unread in a room the user has no subscription for: never joined, was removed, or only previewed a public channel without joining; calling with a message id belonging to a room the account cannot see.","commonSituations":"Stale UI offering unread for rooms the user was removed from; directory/preview flows where the room is visible but not joined; race between joining and acting.","solutions":["Ensure the user joined the room (subscription exists) before enabling mark-unread","Refresh subscriptions after kick/remove events and hide such rooms","Join the room first when acting on previewed public channels"],"exampleFix":"// before\nMeteor.call('unreadMessages', { _id: messageId }); // not a member\n\n// after\nconst sub = Subscriptions.findOne({ rid: message.rid });\nif (sub) {\n  Meteor.call('unreadMessages', { _id: messageId });\n} else {\n  Meteor.call('joinRoom', message.rid);","handlingStrategy":"validation","validationCode":"const sub = await Subscriptions.findOneByRoomIdAndUserId(message.rid, userId);\nif (!sub?.ls) {\n  return; // no membership/last-seen: unread is not applicable\n}\nawait unreadMessages(userId, { _id: message._id });","typeGuard":null,"tryCatchPattern":"Meteor.call('unreadMessages', { _id }, undefined, (err) => {\n  if (err?.error === 'error-subscription-not-found') {\n    hideRoomAndResync(message.rid); // user is not a member anymore\n  }\n});","preventionTips":["Gate unread actions on a locally cached subscription that has an ls timestamp","After kick/remove stream events, drop unread affordances for that room","Join before acting when interacting with previewed public channels"],"tags":["unread","subscription","room-membership","ddp-method"],"backgroundTag":"subscription-not-found","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}