RocketChat/Rocket.Chat · error · Meteor.Error
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
createRoom refuses to add federated members (usernames containing '@' and ':', the Matrix-style identifier shape) unless the room is explicitly marked federated (extraData.federated === true). This guard prevents accidentally mixing remote users into a purely local room.
Source
Thrown at apps/meteor/server/lib/rooms/createRoom.ts:168
options?: ICreateRoomParams['options'],
): Promise<
ICreatedRoom & {
rid: string;
}
> => {
const { teamId, ...extraData } = roomExtraData || ({} as IRoom);
// TODO: use a shared helper to check whether a user is federated
const hasFederatedMembers = members.some((member) => {
if (typeof member === 'string') {
return member.includes(':') && member.includes('@');
}
return member.username?.includes(':') && member.username?.includes('@');
});
// Prevent adding federated users to rooms that are not marked as federated explicitly
if (hasFederatedMembers && extraData.federated !== true) {
throw new Meteor.Error('error-federated-users-in-non-federated-rooms', 'Cannot add federated users to non-federated rooms', {
method: 'createRoom',
});
}
await prepareCreateRoomCallback.run({
type,
// name,
// owner: ownerUsername,
// members,
// readOnly,
extraData,
// options,
});
const shouldBeHandledByFederation = extraData.federated === true;
if (shouldBeHandledByFederation && owner && !isUserNativeFederated(owner) && !(await FederationMatrix.canUserAccessFederation(owner))) {
throw new Meteor.Error('error-not-authorized-federation', 'Not authorized to access federation', {View on GitHub (pinned to b2c16d5842)
Solutions
- Pass federated: true in roomExtraData when any member is a federated user
- Filter federated usernames out of members when creating a local-only room
- Validate member usernames before calling createRoom and fail early with a clear message
Example fix
// before
createRoom('c', name, owner, ['alice', 'bob:matrix.org@remote'], {});
// after
createRoom('c', name, owner, ['alice', 'bob:matrix.org@remote'], { federated: true }); Defensive patterns
Strategy: type-guard
Validate before calling
const FEDERATED_RE = /[:@]/;
const membersAreFederated = members.some(m =>
typeof m === 'string' ? FEDERATED_RE.test(m) : Boolean(m.username && m.includes(':') && m.includes('@'))
);
if (membersAreFederated && extraData?.federated !== true) {
extraData = { ...extraData, federated: true };
} Type guard
const isFederatedUsername = (username: string): boolean => username.includes(':') && username.includes('@'); Try / catch
try {
await createRoom(type, name, owner, members, extraData);
} catch (err) {
if (err instanceof Meteor.Error && err.error === 'error-federated-users-in-non-federated-rooms') {
// decide: drop federated members OR set extraData.federated = true and retry
}
throw err;
} Prevention
- Centralize a isFederatedUsername helper instead of inline string checks
- Validate member shapes at the API boundary (REST schema) so federated flags cannot be forgotten
- Add tests covering mixed local/remote member lists
When it happens
Trigger: Calling createRoom (type other than 'd') with a members array containing a string like 'user:server.tld@external-host' or a user object whose username contains ':' and '@', while roomExtraData is omitted or federated is not exactly true.
Common situations: Apps or REST/API callers copying a member list that includes federated usernames but forgetting { federated: true } in roomExtraData; federation recently enabled and existing automation reusing old payloads; string vs boolean coercion bugs where federated is passed as 'true' or 1.
Related errors
- error-invalid-members
- error-creator-not-in-room
- error-invalid-room
- error-federated-users-in-non-federated-rooms
- Federated user not found locally
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/e61b99046ff53994.
Report an issue: GitHub.