RocketChat/Rocket.Chat · error · Meteor.Error
not-authorized
not-authorized
Error message
Not Authorized
What it means
starMessage verifies room visibility with canAccessRoomAsync(room, { _id: user._id }); failure throws Meteor.Error('not-authorized', 'Not Authorized'). The user still holds a subscription row (checked earlier), but the authorization engine currently denies access - role or permission changes, room type changes, or app-user restrictions.
Source
Thrown at apps/meteor/server/lib/messaging/stars/starMessage.ts:45
const subscription = await Subscriptions.findOneByRoomIdAndUserId(message.rid, user._id, {
projection: { _id: 1 },
});
if (!subscription) {
return false;
}
if (!(await Messages.findOneByRoomIdAndMessageId(message.rid, message._id))) {
return false;
}
const room = await Rooms.findOneById(message.rid, { projection: { ...roomAccessAttributes, lastMessage: 1 } });
if (!room) {
throw new Meteor.Error('error-not-allowed', 'Not allowed', { method: 'starMessage' });
}
if (!(await canAccessRoomAsync(room, { _id: user._id }))) {
throw new Meteor.Error('not-authorized', 'Not Authorized', { method: 'starMessage' });
}
if (isTheLastMessage(room, message)) {
await Rooms.updateLastMessageStar(room._id, user._id, message.starred);
void notifyOnRoomChangedById(room._id);
}
await Apps.self?.triggerEvent(AppEvents.IPostMessageStarred, message, user, message.starred);
await Messages.updateUserStarById(message._id, user._id, message.starred);
void notifyOnMessageChange({
id: message._id,
});
return true;
};
View on GitHub (pinned to b2c16d5842)
Solutions
- In integrations, mirror the server check with canAccessRoomAsync before calling starMessage
- Refresh the user's roles/permissions and room list after authorization changes
- For app users, grant room access or switch to a user context that has membership
Example fix
// before
await starMessage(appUser, { rid, _id: messageId, starred: true });
// after
if (await canAccessRoomAsync(room, appUser)) {
await starMessage(appUser, { rid, _id: messageId, starred: true }); Defensive patterns
Strategy: validation
Validate before calling
if (await canAccessRoomAsync(room, { _id: user._id })) {
await starMessage(user, message);
} else {
await resyncRoomAccess(message.rid);
} Try / catch
Meteor.call('starMessage', msg, (err) => {
if (err?.error === 'not-authorized') {
resyncRoomAccess(msg.rid); // access revoked - drop the local room view
}
}); Prevention
- Mirror canAccessRoomAsync in any integration before calling starMessage
- Listen for role/permission change events and invalidate cached room access
- Treat not-authorized as terminal for the current user+room pair
When it happens
Trigger: Starring in a room where access was revoked at the permission layer while the subscription row lingers: roles stripped, private channel converted or restricted, app users blocked from encrypted/private rooms, DM counterpart deletion.
Common situations: Permission revocation racing a star action; apps starring with a user context that cannot access the room; stale subscription rows after access revocation.
Related errors
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/68023e9d3efdb1b0.
Report an issue: GitHub.