{"record":{"id":"64bdc94b146bf97e","repo":"RocketChat/Rocket.Chat","slug":"error-invalid-room-64bdc9","errorCode":"error-invalid-room","errorMessage":"error-invalid-room","messagePattern":"error-invalid-room","errorType":"error_code","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/lib/messages/loadMessageHistory.ts","lineNumber":32,"sourceCode":"\tls,\n\tshowThreadMessages = true,\n\toffset = 0,\n\troom: providedRoom,\n}: {\n\t// userId is undefined if user is reading anonymously\n\tuserId?: string;\n\trid: string;\n\tend: Date | undefined;\n\tlimit?: number;\n\tls?: string | Date;\n\tshowThreadMessages?: boolean;\n\toffset?: number;\n\troom?: IRoom;\n}) {\n\tconst room = providedRoom ?? (await Rooms.findOneById(rid, { projection: { sysMes: 1 } }));\n\n\tif (!room) {\n\t\tthrow new Error('error-invalid-room');\n\t}\n\n\tconst hiddenSystemMessages = settings.get<MessageTypesValues[]>('Hide_System_Messages');\n\n\tconst hiddenMessageTypes = getHiddenSystemMessages(room, hiddenSystemMessages);\n\n\tconst options: FindOptions<IMessage> = {\n\t\tsort: {\n\t\t\tts: -1,\n\t\t},\n\t\tlimit,\n\t\tskip: offset,\n\t};\n\n\tconst records = end\n\t\t? await Messages.findVisibleByRoomIdBeforeTimestampNotContainingTypes(\n\t\t\t\trid,\n\t\t\t\tend,","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/lib/messages/loadMessageHistory.ts#L14-L50","documentation":"loadMessageHistory (apps/meteor/server/lib/messages/loadMessageHistory.ts:29-33) resolves the room via Rooms.findOneById(rid) unless the caller passes a preloaded room object; if neither yields a room it throws a plain Error 'error-invalid-room'. This powers history loading (loadHistory and related loaders), and the rid comes straight from the requesting client.","triggerScenarios":"Requesting history for a rid that does not exist (typo, stale id from another workspace); the room was deleted while the client still had it open; deep-linking to a room the server no longer has; passing an empty rid string.","commonSituations":"Clients with stale local storage after workspace resets/imports; rooms deleted by retention policies or moderators while users keep tabs open; copy-paste or URL-manipulation bugs producing malformed rids; test environments pointing at a different database.","solutions":["Verify the rid exists (Rooms.findOneById) or reuse the room document you already loaded and pass it as loadMessageHistory's room parameter","Refresh/repair the client's room list when this fires - the id is stale","Treat this as 'room gone': close the subscription and clean local caches instead of retrying the same rid","Validate rid format (server-side ids are 17-char Mongo ObjectIds) before calling"],"exampleFix":"// before\nconst history = await loadMessageHistory({ rid, end, ls });\n\n// after\nconst room = await Rooms.findOneById(rid);\nif (!room) return handleRoomGone(rid);\nconst history = await loadMessageHistory({ rid, end, ls, room });","handlingStrategy":"validation","validationCode":"const room = providedRoom ?? (await Rooms.findOneById(rid));\nif (!room) return handleRoomGone(rid); // close subscription, clear caches\nreturn loadMessageHistory({ rid, end, ls, room });","typeGuard":null,"tryCatchPattern":"try {\n  await loadMessageHistory({ rid, end, ls });\n} catch (error: any) {\n  if (error.message === 'error-invalid-room') {\n    markRoomDeletedLocally(rid); // stale id; stop requesting history for it\n    return;\n  }\n  throw error;\n}","preventionTips":["Pass the already-loaded room object when you have it","Validate rid shape (17-char id) before calling","Drop local room caches when this fires - the id no longer exists"],"tags":["messages","history","room","not-found","input-validation"],"backgroundTag":"room-not-found","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}