RocketChat/Rocket.Chat · error · MeteorError

error-invalid-room

error-invalid-room

Error message

Invalid room

What it means

Thrown by the federation `afterCreateRoom`-style hook when, after marking a room as federated, the room cannot be re-fetched from the DB OR the fetched room fails `isRoomNativeFederated()`. It is a `MeteorError` with code `error-invalid-room`. The check guards the subsequent Matrix invite call so it never runs against a non-federated room record.

Source

Thrown at apps/meteor/ee/server/hooks/federation/index.ts:46

	}

	const federatedRoomId = room?.federation?.mrid;
	if (!federatedRoomId) {
		await FederationMatrix.createRoom(room, owner);
	} else {
		// TODO unify how to get server
		// matrix room was already created and passed
		const fromServer = federatedRoomId.split(':')[1];

		await Rooms.setAsFederated(room._id, {
			mrid: federatedRoomId,
			origin: fromServer,
		});
	}

	const federationRoom = await Rooms.findOneById(room._id);
	if (!federationRoom || !isRoomNativeFederated(federationRoom)) {
		throw new MeteorError('error-invalid-room', 'Invalid room');
	}

	// TODO this won't be neeeded once we receive all state events at ee/packages/federation-matrix/src/events/member.ts
	await FederationMatrix.inviteUsersToRoom(
		federationRoom,
		members.filter((member) => member !== owner.username),
		owner,
	);
});

callbacks.add(
	'afterSaveMessage',
	async (message, { room, user }) => {
		if (!FederationActions.shouldPerformFederationAction(room)) {
			return;
		}

		try {

View on GitHub (pinned to f9d3ec372b)

Solutions

  1. Verify the room still exists and its `federation` field is populated before the hook runs.
  2. Check `setAsFederated` succeeded (no write errors) and the mrid/origin were stored.
  3. Confirm `isRoomNativeFederated()` criteria match the room record shape in the current version.
Defensive patterns

Strategy: validation

Validate before calling

import { isRoomNativeFederated } from '@rocket.chat/core-typings';
import { Rooms } from '../../../../server/models';

async function roomIsFederatedAndValid(roomId: string): Promise<boolean> {
	const room = await Rooms.findOneById(roomId);
	return Boolean(room && isRoomNativeFederated(room));
}

Type guard

function isInvalidFederatedRoomError(e: unknown): boolean {
	return e instanceof Meteor.Error && (e as Meteor.Error).error === 'error-invalid-room';
}

Try / catch

try {
	await callbacks.run('afterCreateRoom', room, members, owner);
} catch (e) {
	if (e instanceof Meteor.Error && e.error === 'error-invalid-room') {
		// room not federated after setAsFederated — investigate DB write
	}
	throw e;
}

Prevention

When it happens

Trigger: Inside the federation room-creation hook: `Rooms.findOneById(room._id)` returns null, or the returned room is not native-federated (missing/invalid `federation` field) after the `setAsFederated` step.

Common situations: Race condition where the room was deleted between creation and re-fetch; `setAsFederated` failed silently or the federation data shape changed; a non-federated room erroneously entered the federation hook path due to a routing bug.

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12). Data as JSON: /api/errors/9acabf4136f5a145. Report an issue: GitHub.