RocketChat/Rocket.Chat · error · Meteor.Error

error-invalid-user

error-invalid-user

Error message

Invalid user

What it means

Thrown by the deprecated getRoomNameById Meteor method when the connection has no authenticated user (Meteor.userId() is null). The method is slated for removal in 9.0.0 in favor of /v1/rooms.info, and every call first logs a deprecation warning before the auth guard rejects anonymous connections.

Source

Thrown at apps/meteor/server/meteor-methods/rooms/getRoomNameById.ts:23

import { Meteor } from 'meteor/meteor';

import { hasPermissionAsync } from '../../lib/authorization/hasPermission';
import { methodDeprecationLogger } from '../../lib/deprecationWarningLogger';

declare module '@rocket.chat/ddp-client' {
	// eslint-disable-next-line @typescript-eslint/naming-convention
	interface ServerMethods {
		getRoomNameById(rid: IRoom['_id']): Promise<string | undefined>;
	}
}

Meteor.methods<ServerMethods>({
	async getRoomNameById(rid) {
		methodDeprecationLogger.method('getRoomNameById', '9.0.0', '/v1/rooms.info');
		check(rid, String);
		const userId = Meteor.userId();
		if (!userId) {
			throw new Meteor.Error('error-invalid-user', 'Invalid user', {
				method: 'getRoomNameById',
			});
		}

		const room = await Rooms.findOneById(rid);

		if (room == null) {
			throw new Meteor.Error('error-not-allowed', 'Not allowed', {
				method: 'getRoomNameById',
			});
		}

		const subscription = await Subscriptions.findOneByRoomIdAndUserId(rid, userId, {
			projection: { _id: 1 },
		});
		if (subscription) {
			return room.name;
		}

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Ensure login is complete before calling (guard on Meteor.userId())
  2. Re-authenticate to get a fresh resume token
  3. Replace with GET /api/v1/rooms.info?roomId=... and read room.name from the response

Example fix

// before (deprecated, fails when anonymous)
const name = await Meteor.callAsync('getRoomNameById', rid);

// after - REST with auth headers
const res = await fetch('/api/v1/rooms.info?roomId=' + encodeURIComponent(rid), {
  headers: { 'X-Auth-Token': token, 'X-User-Id': uid },
});
const name = (await res.json()).room?.name;
Defensive patterns

Strategy: validation

Validate before calling

if (!Meteor.userId()) {
  throw new Error('login required');
}
const name = await Meteor.callAsync('getRoomNameById', rid);

Type guard

// returns Promise<string | undefined>
const isRoomName = (v: string | undefined): v is string => typeof v === 'string';
const name = await Meteor.callAsync('getRoomNameById', rid);
if (isRoomName(name)) render(name);

Try / catch

try {
  const name = await Meteor.callAsync('getRoomNameById', rid);
} catch (e) {
  if (e instanceof Meteor.Error && e.error === 'error-invalid-user') {
    showLoginScreen();
  }
}

Prevention

When it happens

Trigger: Meteor.call('getRoomNameById', rid) executed pre-login, post-logout, or with an expired resume token; legacy client code resolving display names for room ids during startup before the session is restored.

Common situations: Older clients or apps-engine packages still on the DDP method; notifications/webhook rendering code that runs without a user context; token invalidation after user password reset or admin session purge.

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18). Data as JSON: /api/errors/f6c5363725814a0f. Report an issue: GitHub.