RocketChat/Rocket.Chat · error · Error
message-not-found
Error message
message-not-found
What it means
getPermaLink() throws 'message-not-found' when the message is neither in the local Messages store (Messages.state.get(msgId)) nor fetchable via GET /v1/chat.getMessage (getMessage() swallows errors and returns null). It means the permalink target genuinely cannot be resolved by this client.
Solutions
- Verify the message id exists and the user has read access to its room.
- Handle the throw and surface a 'message not available' state instead of a broken link.
- If the message should exist, retry once the network/permissions settle.
Example fix
// before
const url = await getPermaLink(msgId);
// after
try {
const url = await getPermaLink(msgId);
} catch (e) {
if (e instanceof Error && e.message === 'message-not-found') {
dispatchToastMessage({ type: 'error', message: 'Message no longer available' });
return;
}
throw e;
} Defensive patterns
Strategy: try-catch
Validate before calling
if (!Messages.state.get(msgId)) {
try {
await sdk.rest.get('/v1/chat.getMessage', { msgId });
} catch {
return; // gone or inaccessible — skip permalink generation
}
}
const url = await getPermaLink(msgId); Try / catch
try {
const url = await getPermaLink(msgId);
} catch (e) {
if (e instanceof Error && e.message === 'message-not-found') {
dispatchToastMessage({ type: 'error', message: 'Message no longer available' });
return;
}
throw e;
} Prevention
- Confirm read access to the message's room before generating permalinks.
- Expect permalinks to deleted messages to fail — keep a graceful fallback UI.
- Note getMessage() swallows REST errors, so network failures surface as not-found too.
When it happens
Trigger: Building a permalink for a deleted message, a message in a room the user cannot read, or an id that does not exist on this server; also when the REST call fails (network, permission) — the catch converts that to the same throw.
Common situations: Copy-link on a message removed moments earlier; permalinks shared across workspaces; API token without read access to the target room; offline moment during the fallback fetch.
Related errors
AI-assisted analysis of RocketChat/Rocket.Chat@2f18297792 (2026-08-18).
Data as JSON: /api/errors/8096da246c9dd1e8.
Report an issue: GitHub.
Appendix: source
Thrown at apps/meteor/client/lib/getPermaLink.ts:24
try {
const { sdk } = await import('./SDKClient');
const { message } = await sdk.rest.get('/v1/chat.getMessage', { msgId });
return message;
} catch {
return null;
}
};
export const getPermaLink = async (msgId: string): Promise<string> => {
if (!msgId) {
throw new Error('invalid-parameter');
}
const { Messages, Rooms, Subscriptions } = await import('../stores');
const msg = Messages.state.get(msgId) || (await getMessage(msgId));
if (!msg) {
throw new Error('message-not-found');
}
const roomData = Rooms.state.get(msg.rid);
if (!roomData) {
throw new Error('room-not-found');
}
const subData = Subscriptions.state.find((record) => record.rid === roomData._id && record.u._id === getUserId());
const { roomCoordinator } = await import('./rooms/roomCoordinator');
const roomURL = roomCoordinator.getURL(roomData.t, { ...(subData || roomData), tab: '' });
return `${roomURL}?msg=${msgId}`;
};
View on GitHub (pinned to 2f18297792)