RocketChat/Rocket.Chat · error · Error
error-message-not-found
Error message
error-message-not-found
What it means
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.
Source
Thrown at apps/meteor/server/api/v1/push.ts:311
authRequired: true,
query: isPushGetProps,
response: {
200: pushGetResponseSchema,
400: validateBadRequestErrorResponse,
401: validateUnauthorizedErrorResponse,
},
},
async function action() {
const { id } = this.queryParams;
const receiver = await Users.findOneById(this.userId);
if (!receiver) {
throw new Error('error-user-not-found');
}
const message = await Messages.findOneById(id);
if (!message) {
throw new Error('error-message-not-found');
}
const room = await Rooms.findOneById(message.rid);
if (!room) {
throw new Error('error-room-not-found');
}
if (!(await canAccessRoomAsync(room, receiver))) {
throw new Error('error-not-allowed');
}
const data = await PushNotification.getNotificationForMessageId({ receiver, room, message });
return API.v1.success({ data });
},
)
.get(
'push.info',View on GitHub (pinned to f9d3ec372b)
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.
Example fix
// before
await fetch(`/api/v1/push.get?id=${id}`);
// after
const exists = await fetch(`/api/v1/chat.getMessage?msgId=${id}`).then(r => r.json());
if (!exists.message) {
// message no longer available; skip push info fetch
return null;
}
await fetch(`/api/v1/push.get?id=${id}`); Defensive patterns
Strategy: validation
Validate before calling
// Validate message id format and existence before push.get
async function safePushGet(id: string, authHeaders: HeadersInit) {
if (!id || typeof id !== 'string') throw new Error('id required');
const msg = await fetch(`/api/v1/chat.getMessage?msgId=${encodeURIComponent(id)}`, { headers: authHeaders }).then(r => r.json());
if (!msg.success || !msg.message) return null; // message gone, skip
return fetch(`/api/v1/push.get?id=${encodeURIComponent(id)}`, { headers: authHeaders }).then(r => r.json());
} Type guard
function isMessageId(value: unknown): value is string {
return typeof value === 'string' && value.length > 0;
} Try / catch
try {
await fetch(`/api/v1/push.get?id=${id}`).then(r => r.json());
} catch (e) {
// plain Error (not Meteor.Error) -> generic failure; log id and move on
if (String(e).includes('error-message-not-found')) { /* message gone */ }
} Prevention
- 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.
When it happens
Trigger: 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).
Common situations: 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.
Related errors
AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12).
Data as JSON: /api/errors/745e9309f820c64f.
Report an issue: GitHub.