RocketChat/Rocket.Chat · error · Meteor.Error

error-invalid-room

error-invalid-room

Error message

Invalid room

What it means

getThreadsList (deprecated in 9.0.0 in favor of GET /v1/chat.getThreadsList) throws error-invalid-room when its rid parameter is not a string — a manual typeof check placed before the room lookup. It is not a 'room not found' signal: a well-typed but unknown or inaccessible rid instead produces error-not-allowed further down (getThreadsList.ts:39-41). The error means the client sent undefined, null, a number, or an object where the room _id string was expected.

Source

Thrown at apps/meteor/server/meteor-methods/messages/getThreadsList.ts:33

		getThreadsList(params: { rid: IRoom['_id']; limit?: number; skip?: number }): IMessage[];
	}
}

Meteor.methods<ServerMethods>({
	async getThreadsList({ rid, limit = 50, skip = 0 }) {
		methodDeprecationLogger.method('getThreadsList', '9.0.0', '/v1/chat.getThreadsList');
		if (limit > MAX_LIMIT) {
			throw new Meteor.Error('error-not-allowed', `max limit: ${MAX_LIMIT}`, {
				method: 'getThreadsList',
			});
		}

		if (!Meteor.userId() || !settings.get('Threads_enabled')) {
			throw new Meteor.Error('error-not-allowed', 'Threads Disabled', { method: 'getThreadsList' });
		}

		if (typeof rid !== 'string') {
			throw new Meteor.Error('error-invalid-room', 'Invalid room', { method: 'getThreadsList' });
		}

		const user = await Meteor.userAsync();
		const room = await Rooms.findOneById(rid);

		if (!user || !room || !(await canAccessRoomAsync(room, user))) {
			throw new Meteor.Error('error-not-allowed', 'Not Allowed', { method: 'getThreadsList' });
		}

		return Messages.findThreadsByRoomId(room._id, skip, limit).toArray();
	},
});

View on GitHub (pinned to 2a7de45707)

Solutions

  1. Pass the room's _id string; when you hold a room record, send room._id, never the record itself or room.rid.
  2. Skip the call until rid is a non-empty string — guard at the call site or bail out of the reactive effect early.
  3. Fix ordering: wait for route/subscription data to resolve before invoking the method.
  4. Migrate to GET /v1/chat.getThreadsList — the DDP method is deprecated for removal in 9.0.0.

Example fix

// before — `room` is the fetched room DOCUMENT (no rid field on it),
// so rid is undefined and the server throws error-invalid-room
await Meteor.callAsync('getThreadsList', { rid: room.rid, limit: 50 });

// after — pass the room's _id string
await Meteor.callAsync('getThreadsList', { rid: room._id, limit: 50 });
Defensive patterns

Strategy: validation

Validate before calling

const isRoomId = (value: unknown): value is IRoom['_id'] =>
  typeof value === 'string' && value.length > 0;

// inside a reactive effect: skip until the route actually resolved a room id
if (!isRoomId(rid)) {
  return;
}
const threads = Meteor.call('getThreadsList', { rid, limit: 50, skip: 0 });

Type guard

const isRoomId = (value: unknown): value is IRoom['_id'] =>
  typeof value === 'string' && value.length > 0;

Try / catch

try {
  const threads = Meteor.call('getThreadsList', { rid, limit: 50 });
} catch (error) {
  if (error instanceof Meteor.Error && error.error === 'error-invalid-room') {
    // programmer error: rid never reached the call as a string — fix the caller, do NOT retry.
    // unknown-but-valid ids surface as error-not-allowed instead
  }
  throw error;
}

Prevention

When it happens

Trigger: Meteor.call('getThreadsList', { rid, limit, skip }) with rid undefined (e.g., destructured from a route parameter that is not resolved yet), null, a numeric id, or a whole room document instead of room._id. The check fires only after the limit check (default 50, max 100) and the Threads_enabled/authentication checks pass.

Common situations: Router params not yet resolved when a component's effect first runs (rid undefined on first render), state initialized to null, or passing subscription data (the room record) rather than its _id. Common when porting REST integrations to DDP: path-typed string ids in REST become whatever JavaScript value is at hand in a method payload.

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@2a7de45707 (2026-08-21). Data as JSON: /api/errors/20914a3d29f4f5b0. Report an issue: GitHub.