RocketChat/Rocket.Chat · error · Meteor.Error
error-invalid-user
error-invalid-user
Error message
Invalid user
What it means
The followMessage Meteor-method wrapper loads the caller with Meteor.userAsync(); a null result throws 'error-invalid-user'. This happens when the connection has no valid login (or its user record cannot be loaded), independent of the follow logic itself. The method is deprecated since 9.0.0 in favor of POST /v1/chat.followMessage and is rate-limited to 5 calls per 5 seconds per user.
Source
Thrown at apps/meteor/server/meteor-methods/messages/followMessage.ts:59
void notifyOnMessageChange({
id,
});
const isFollowed = true;
await Apps.self?.triggerEvent(AppEvents.IPostMessageFollowed, message, user, isFollowed);
return followResult;
};
Meteor.methods<ServerMethods>({
async followMessage({ mid }) {
methodDeprecationLogger.method('followMessage', '9.0.0', '/v1/chat.followMessage');
check(mid, String);
const user = (await Meteor.userAsync()) as IUser;
if (!user) {
throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'followMessage' });
}
return followMessage(user, { mid });
},
});
RateLimiter.limitMethod('followMessage', 5, 5000, {
userId() {
return true;
},
});
View on GitHub (pinned to b2c16d5842)
Solutions
- Guard with Meteor.userId() before calling; re-login if null
- Migrate to POST /v1/chat.followMessage with an authenticated token (deprecation target)
- On error, re-run the auth flow and retry once
Example fix
// before
Meteor.call('followMessage', { mid });
// after
if (!Meteor.userId()) {
// re-authenticate first
}
Meteor.call('followMessage', { mid }); Defensive patterns
Strategy: validation
Validate before calling
if (!Meteor.userId()) {
// re-authenticate before following threads
} else {
Meteor.call('followMessage', { mid });
} Try / catch
try {
await Meteor.callAsync('followMessage', { mid });
} catch (e) {
if ((e as Meteor.Error).error === 'error-invalid-user') {
// session lost: re-login, then retry once (mind the 5/5s rate limit)
}
} Prevention
- Check Meteor.userId() before calling; the wrapper loads the full user record
- Migrate to POST /v1/chat.followMessage (deprecation target)
- Respect the method rate limit (5 calls per 5000 ms) when retrying
When it happens
Trigger: Meteor.call('followMessage', { mid }) on an unauthenticated or expired DDP session.
Common situations: Follow toggles in UIs left open across logouts; token expiry while a thread view was mounted; integrations toggling follow over DDP without login.
Related errors
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/08eeed4483c9abbe.
Report an issue: GitHub.