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
- Ensure login is complete before calling (guard on Meteor.userId())
- Re-authenticate to get a fresh resume token
- 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
- Migrate to /v1/rooms.info - the method is removed in 9.0.0
- Resolve names lazily and only for rooms already in the user's context
- Cache name results to avoid repeated permission-gated lookups
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.