RocketChat/Rocket.Chat · error · Meteor.Error
error-invalid-message
error-invalid-message
Error message
Invalid message
What it means
Thrown by getReadReceiptsFunction when Messages.findOneById(messageId) returns null. The lookup projects _id, rid, and receiptsArchived; a missing record means the message id does not correspond to an existing message. Code is 'error-invalid-message'.
Source
Thrown at apps/meteor/ee/server/meteor-methods/getReadReceipts.ts:27
import { methodDeprecationLogger } from '../../../server/lib/deprecationWarningLogger';
import { ReadReceipt } from '../lib/message-read-receipt/ReadReceipt';
declare module '@rocket.chat/ddp-client' {
// eslint-disable-next-line @typescript-eslint/naming-convention
interface ServerMethods {
getReadReceipts(options: { messageId: IMessage['_id'] }): IReadReceiptWithUser[];
}
}
export const getReadReceiptsFunction = async function (messageId: IMessage['_id'], userId: string): Promise<IReadReceiptWithUser[]> {
if (!License.hasModule('message-read-receipt')) {
throw new Meteor.Error('error-action-not-allowed', 'This is an enterprise feature', { method: 'getReadReceipts' });
}
check(messageId, String);
const message = await Messages.findOneById(messageId, { projection: { _id: 1, rid: 1, receiptsArchived: 1 } });
if (!message) {
throw new Meteor.Error('error-invalid-message', 'Invalid message', {
method: 'getReadReceipts',
});
}
if (!(await canAccessRoomIdAsync(message.rid, userId))) {
throw new Meteor.Error('error-invalid-room', 'Invalid room', { method: 'getReadReceipts' });
}
return ReadReceipt.getReceipts(message);
};
Meteor.methods<ServerMethods>({
async getReadReceipts({ messageId }) {
methodDeprecationLogger.method('getReadReceipts', '9.0.0', '/v1/chat.getMessageReadReceipts');
check(messageId, String);
const uid = Meteor.userId();View on GitHub (pinned to f9d3ec372b)
Solutions
- Validate the messageId exists (Messages.findOneById) before calling the method.
- Handle the error in the client and close the read-receipt panel with a 'message not found' notice.
- Check retention/purge policies if valid messages disappear.
Example fix
// before
const receipts = await getReadReceiptsFunction(messageId, uid);
// after
const msg = await Messages.findOneById(messageId, { projection: { _id: 1 } });
if (!msg) throw new Error('Message not found');
const receipts = await getReadReceiptsFunction(messageId, uid); Defensive patterns
Strategy: validation
Validate before calling
const msg = await Messages.findOneById(messageId, { projection: { _id: 1 } });
if (!msg) throw new Error('Message not found');
const receipts = await getReadReceiptsFunction(messageId, uid); Type guard
function isMessageId(id: unknown): id is string {
return typeof id === 'string' && id.length > 0;
} Try / catch
try {
await getReadReceiptsFunction(messageId, uid);
} catch (e) {
if (isMeteorError(e, 'error-invalid-message')) {
closeReadReceiptPanel('Message no longer exists.');
return;
}
throw e;
} Prevention
- Validate messageId existence before calling.
- Close the read-receipt panel on delete events.
- Watch retention/purge jobs that remove messages.
When it happens
Trigger: Calling getReadReceipts with a messageId that does not exist, was deleted, or has not been inserted yet (eventual-consistency lag).
Common situations: Client holds a stale message id after deletion; message id mistyped or swapped; a message deleted by retention policy while its read-receipt panel was open.
Related errors
- Invalid token for livechat message
- Invalid editor assigned to the message for the update.
- Invalid message id
- Invalid username
- Unrecognized typing scope provided
AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12).
Data as JSON: /api/errors/c722388c80f5a9f7.
Report an issue: GitHub.