{"record":{"id":"4c62ba021e505509","repo":"RocketChat/Rocket.Chat","slug":"error-invalid-message-id","errorCode":"error-invalid-message_id","errorMessage":"error-invalid-message_id","messagePattern":"error-invalid-message_id","errorType":"exception","errorClass":"Error","httpStatus":400,"severity":"error","filePath":"apps/meteor/server/lib/moderation/reportMessage.ts","lineNumber":19,"sourceCode":"import { Apps, AppEvents } from '@rocket.chat/apps';\nimport type { IMessage, IUser } from '@rocket.chat/core-typings';\nimport { Messages, ModerationReports, Rooms, Users } from '@rocket.chat/models';\n\nimport { canAccessRoomAsync } from '../authorization/canAccessRoom';\n\nexport const reportMessage = async (messageId: IMessage['_id'], description: string, uid: IUser['_id']) => {\n\tif (!uid) {\n\t\tthrow new Error('error-invalid-user');\n\t}\n\n\tif (!description.trim()) {\n\t\tthrow new Error('error-invalid-description');\n\t}\n\n\tconst message = await Messages.findOneById(messageId);\n\n\tif (!message) {\n\t\tthrow new Error('error-invalid-message_id');\n\t}\n\n\tconst user = await Users.findOneById(uid);\n\n\tif (!user) {\n\t\tthrow new Error('error-invalid-user');\n\t}\n\n\tconst { rid } = message;\n\t// If the user can't access the room where the message is, report that the message id is invalid\n\tconst room = await Rooms.findOneById(rid);\n\tif (!room || !(await canAccessRoomAsync(room, { _id: uid }))) {\n\t\tthrow new Error('error-invalid-message_id');\n\t}\n\n\tconst reportedBy = {\n\t\t_id: user._id,\n\t\tusername: user.username,","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/lib/moderation/reportMessage.ts#L1-L37","documentation":"Thrown by reportMessage (Rocket.Chat moderation reporting) when Messages.findOneById(messageId) returns null, i.e. no message document matches the supplied ID. The server treats a nonexistent target message as invalid input rather than a permission problem. Most often the message was deleted before the report was submitted, or the caller passed a room ID (rid) instead of the message _id.","triggerScenarios":"Calling the moderation report flow (reportMessage server lib / moderation.report API) with a messageId that was deleted, an ID copied from the wrong field (rid instead of message _id), or a fabricated ID in tests where the Messages collection was never seeded.","commonSituations":"Report dialog left open while the message gets deleted; moderation bots acting on stale IDs; test fixtures that create rooms/users but no messages; passing undefined or an object as messageId.","solutions":["Confirm you are passing the message _id, not the room rid or another field","Re-fetch the message right before reporting to confirm it still exists","In the UI, treat this error as 'message no longer exists' instead of offering a retry","In tests, seed the Messages collection before invoking reportMessage"],"exampleFix":"// before\nawait reportMessage(rid, description, uid); // room id passed by mistake\n\n// after\nawait reportMessage(message._id, description, Meteor.userId());","handlingStrategy":"validation","validationCode":"const message = await Messages.findOneById(messageId, { projection: { _id: 1, rid: 1 } });\nif (!message) {\n  // do not call reportMessage; the target no longer exists\n  throw new Error('message not found');\n}","typeGuard":null,"tryCatchPattern":"try {\n  await reportMessage(messageId, description, uid);\n} catch (err) {\n  if (err instanceof Error && err.message === 'error-invalid-message_id') {\n    // treat as 'message deleted or not visible' - do not retry blindly\n  } else throw err;\n}","preventionTips":["Report from freshly rendered message state, not long-cached lists","Always pass the message _id, never the rid","Seed messages in test fixtures before exercising the report flow"],"tags":["moderation","message","invalid-id","rocket-chat"],"backgroundTag":"entity-not-found","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}