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

  1. Guard with Meteor.userId() before calling; re-login if null
  2. Migrate to POST /v1/chat.followMessage with an authenticated token (deprecation target)
  3. 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

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.