RocketChat/Rocket.Chat · error · MeteorError
error-federated-users-in-non-federated-rooms
error-federated-users-in-non-federated-rooms
Error message
Cannot add federated users to non-federated rooms
What it means
Thrown from the beforeAddUsersToRoom hook when someone invites usernames that look federated (they pass validateFederatedUsername, i.e. contain a server suffix like 'user@server.tld') into a room that is NOT federated (FederationActions.shouldPerformFederationAction(room) is false). Non-federated rooms physically cannot contain external federated users, so the invite is rejected before any subscription is created.
Solutions
- Invite only local usernames (no colon suffix) to the non-federated room
- If external users must join, create/use a federated channel so FederationActions.shouldPerformFederationAction(room) is true
- Filter the username list before calling the API (see validationCode) so federated handles are routed to a federated room instead
Example fix
// before: mixing external usernames into a local room
await addUsersToRoom(['alice', 'bob@guest.matrix.org'], room, inviter);
// after: route federated usernames to a federated room only
import { validateFederatedUsername } from '@rocket.chat/federation-matrix';
const federated = usernames.filter((u) => validateFederatedUsername(u));
const local = usernames.filter((u) => !validateFederatedUsername(u));
if (federated.length && !isRoomNativeFederated(room)) {
throw new Error('Use a federated room for: ' + federated.join(', '));
}
await addUsersToRoom(local, room, inviter); Defensive patterns
Strategy: validation
Validate before calling
import { validateFederatedUsername } from '@rocket.chat/federation-matrix';
import { isRoomNativeFederated } from '@rocket.chat/core-typings';
const canInviteAll = (room: IRoom, usernames: string[]): boolean =>
isRoomNativeFederated(room) || usernames.every((u) => !validateFederatedUsername(u)); Type guard
import { validateFederatedUsername } from '@rocket.chat/federation-matrix';
const isFederatedUsername = (u: string): boolean => validateFederatedUsername(u); Try / catch
try {
await addUsersToRoom(usernames, room, inviter);
} catch (err: any) {
if (err?.error === 'error-federated-users-in-non-federated-rooms') {
// split the list: invite local users here, federated ones via a federated room
}
throw err;
} Prevention
- Filter invite lists with validateFederatedUsername before calling rooms.invite
- Make invite UIs distinguish federated handles visually so users pick the right room type
- When federation is used heavily, default new channels to federated where appropriate
When it happens
Trigger: Calling addUsersToRoom / invite with a federated username on a regular local channel; REST API rooms.invite with a federated username targeting a non-federated room; UI invite autocomplete picking a federated user while federation is disabled for that room.
Common situations: Workspace has federation enabled globally but the specific room was created as non-federated; users copy a federated handle from another workspace; scripts that bulk-invite usernames without filtering external ones.
Related errors
- error-creator-not-in-room
- error-federated-users-in-non-federated-rooms
- duplicated-account
- Edit_Federated_User_Not_Allowed
- error-app-prevented
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/3762f67601ef337e.
Report an issue: GitHub.
Appendix: source
Thrown at apps/meteor/ee/server/hooks/federation/index.ts:105
// deletion came from federation — don't echo
if (isUserNativeFederated(user)) {
return;
}
if (FederationActions.shouldPerformFederationAction(room)) {
await FederationMatrix.deleteMessage(room.federation.mrid, message);
}
},
callbacks.priority.MEDIUM,
'native-federation-after-delete-message',
);
beforeAddUsersToRoom.add(async ({ usernames, inviter }, room) => {
if (!FederationActions.shouldPerformFederationAction(room) && inviter) {
// check if trying to invite a federated user to a non-federated room
const federatedUsernames = usernames.filter((u) => validateFederatedUsername(u));
if (federatedUsernames.length > 0) {
throw new MeteorError('error-federated-users-in-non-federated-rooms', 'Cannot add federated users to non-federated rooms');
}
return;
}
// we create local users before adding them to the room
await FederationMatrix.ensureFederatedUsersExistLocally(usernames);
});
beforeAddUserToRoom.add(
async ({ user, inviter }, room) => {
if (!user.username || !inviter) {
return;
}
if (!FederationActions.shouldPerformFederationAction(room)) {
return;
}
View on GitHub (pinned to b2c16d5842)