{"record":{"id":"9b74ac6c1f52ba53","repo":"RocketChat/Rocket.Chat","slug":"error-room-does-not-exist-9b74ac","errorCode":"error-room-does-not-exist","errorMessage":"This room does not exist","messagePattern":"This room does not exist","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/meteor-methods/messages/readThreads.ts","lineNumber":41,"sourceCode":"\n\t\tcheck(tmid, String);\n\n\t\tif (!Meteor.userId() || !settings.get('Threads_enabled')) {\n\t\t\tthrow new Meteor.Error('error-not-allowed', 'Threads Disabled', {\n\t\t\t\tmethod: 'getThreadMessages',\n\t\t\t});\n\t\t}\n\n\t\tconst thread = await Messages.findOneById(tmid);\n\t\tif (!thread) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst user = (await Meteor.userAsync()) ?? undefined;\n\n\t\tconst room = await Rooms.findOneById(thread.rid);\n\t\tif (!room) {\n\t\t\tthrow new Meteor.Error('error-room-does-not-exist', 'This room does not exist', { method: 'getThreadMessages' });\n\t\t}\n\n\t\tif (!(await canAccessRoomAsync(room, user))) {\n\t\t\tthrow new Meteor.Error('error-not-allowed', 'Not allowed', { method: 'getThreadMessages' });\n\t\t}\n\n\t\tawait callbacks.run('beforeReadMessages', thread.rid, user?._id);\n\t\tif (user?._id) {\n\t\t\tawait readThread({ user: user as IUser, room, tmid });\n\t\t}\n\t},\n});\n","sourceCodeStart":23,"sourceCodeEnd":54,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/meteor-methods/messages/readThreads.ts#L23-L54","documentation":"readThreads resolves the thread message by tmid and then loads its parent room with Rooms.findOneById(thread.rid). If that lookup returns null the method throws error-room-does-not-exist: the thread message still exists but the room record it points to is gone, so the server cannot authorize or mark the read.","triggerScenarios":"Calling readThreads with a tmid whose room was deleted while thread messages survived (incomplete cascade delete); data drift after a failed import or partial restore where Messages were copied without their Rooms; tmid from another workspace after database surgery.","commonSituations":"Client keeps a thread panel open from cache after the room was deleted; retention/pruning jobs removed rooms but not all thread messages; imports that replicated messages without enforcing room references.","solutions":["Verify the thread's room still exists before marking the thread read; treat missing rooms as stale client state","Find and repair orphaned messages (Messages whose rid has no Rooms entry) or delete them","Refresh client caches so deleted rooms disappear from the UI and the call is never made"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n\tawait Meteor.callAsync('readThreads', tmid);\n} catch (e: any) {\n\tif (e?.error === 'error-room-does-not-exist') {\n\t\t// orphaned thread: room was deleted, close the thread panel and forget tmid\n\t\tcloseThread(tmid);\n\t\treturn;\n\t}\n\tthrow e;\n}","preventionTips":["Invalidate cached thread ids when the owning room disappears from the rooms subscription","Run periodic integrity checks for Messages whose rid has no Rooms entry","Treat deleted-room errors as terminal state, never as retryable"],"tags":["meteor-method","threads","rooms","data-integrity"],"backgroundTag":"room-not-found","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}