{"record":{"id":"745e9309f820c64f","repo":"RocketChat/Rocket.Chat","slug":"error-message-not-found-745e93","errorCode":null,"errorMessage":"error-message-not-found","messagePattern":"error-message-not-found","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/api/v1/push.ts","lineNumber":311,"sourceCode":"\t\t\tauthRequired: true,\n\t\t\tquery: isPushGetProps,\n\t\t\tresponse: {\n\t\t\t\t200: pushGetResponseSchema,\n\t\t\t\t400: validateBadRequestErrorResponse,\n\t\t\t\t401: validateUnauthorizedErrorResponse,\n\t\t\t},\n\t\t},\n\t\tasync function action() {\n\t\t\tconst { id } = this.queryParams;\n\n\t\t\tconst receiver = await Users.findOneById(this.userId);\n\t\t\tif (!receiver) {\n\t\t\t\tthrow new Error('error-user-not-found');\n\t\t\t}\n\n\t\t\tconst message = await Messages.findOneById(id);\n\t\t\tif (!message) {\n\t\t\t\tthrow new Error('error-message-not-found');\n\t\t\t}\n\n\t\t\tconst room = await Rooms.findOneById(message.rid);\n\t\t\tif (!room) {\n\t\t\t\tthrow new Error('error-room-not-found');\n\t\t\t}\n\n\t\t\tif (!(await canAccessRoomAsync(room, receiver))) {\n\t\t\t\tthrow new Error('error-not-allowed');\n\t\t\t}\n\n\t\t\tconst data = await PushNotification.getNotificationForMessageId({ receiver, room, message });\n\n\t\t\treturn API.v1.success({ data });\n\t\t},\n\t)\n\t.get(\n\t\t'push.info',","sourceCodeStart":293,"sourceCodeEnd":329,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/server/api/v1/push.ts#L293-L329","documentation":"Thrown by GET push.get when Messages.findOneById(id) returns no document. The lookup uses the id query param (validated by isPushGetProps). Note this is a plain new Error('error-message-not-found'), not a Meteor.Error, so it surfaces as a generic 500-style failure rather than a structured error body. It guards the push-notification retrieval path before room access is even checked.","triggerScenarios":"GET /api/v1/push.get?id=<id> where id does not match any message document (typo, deleted message, id from another workspace, or id omitted/null despite the query schema).","commonSituations":"Client caches a stale message id; the message was hard-deleted between notification dispatch and the info fetch; integration passes a thread/discussion parent id instead of the actual message _id.","solutions":["Confirm the message _id via GET /api/v1/chat.getMessage?msgId=<id> before calling push.get.","Verify the id was copied from the notification payload's message id field, not the room or thread id.","Handle the error gracefully on the client (the message may legitimately be gone) rather than retrying the same id.","If the error body is unstructured (plain Error), check server logs for the exact throw site to distinguish it from error-room-not-found."],"exampleFix":"// before\nawait fetch(`/api/v1/push.get?id=${id}`);\n\n// after\nconst exists = await fetch(`/api/v1/chat.getMessage?msgId=${id}`).then(r => r.json());\nif (!exists.message) {\n  // message no longer available; skip push info fetch\n  return null;\n}\nawait fetch(`/api/v1/push.get?id=${id}`);","handlingStrategy":"validation","validationCode":"// Validate message id format and existence before push.get\nasync function safePushGet(id: string, authHeaders: HeadersInit) {\n  if (!id || typeof id !== 'string') throw new Error('id required');\n  const msg = await fetch(`/api/v1/chat.getMessage?msgId=${encodeURIComponent(id)}`, { headers: authHeaders }).then(r => r.json());\n  if (!msg.success || !msg.message) return null; // message gone, skip\n  return fetch(`/api/v1/push.get?id=${encodeURIComponent(id)}`, { headers: authHeaders }).then(r => r.json());\n}","typeGuard":"function isMessageId(value: unknown): value is string {\n  return typeof value === 'string' && value.length > 0;\n}","tryCatchPattern":"try {\n  await fetch(`/api/v1/push.get?id=${id}`).then(r => r.json());\n} catch (e) {\n  // plain Error (not Meteor.Error) -> generic failure; log id and move on\n  if (String(e).includes('error-message-not-found')) { /* message gone */ }\n}","preventionTips":["Always source the id from the notification payload's message id field, never from a room/thread id.","Treat 'message not found' as terminal, not retriable."],"tags":["push","rest-api","not-found","message"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}