RocketChat/Rocket.Chat · error · Meteor.Error

error-action-not-allowed

error-action-not-allowed

Error message

Editing an ABAC managed room's ${fieldName} is not allowed

What it means

Thrown by saveRoomSettings (DDP method) from guardABACManagedField when saving roomTopic, roomAnnouncement, or roomDescription with a value that differs from the current one on an ABAC-managed room. A room is ABAC-managed when it is private (t === 'p'), the ABAC_Enabled server setting is on, and its abacAttributes array is non-empty — meaning the room's profile fields are governed by the identity provider's SAML/ABAC attribute mapping and must not be edited locally. Unchanged values pass through untouched, so this only fires on an actual change (including clearing a set field or setting an empty one).

Source

Thrown at apps/meteor/server/meteor-methods/rooms/saveRoomSettings.ts:85

const isAbacManagedTeam = (team: Partial<ITeam> | null, teamRoom: IRoom): boolean => {
	return (
		team?.type === TeamType.PRIVATE &&
		settings.get<boolean>('ABAC_Enabled') &&
		Array.isArray(teamRoom?.abacAttributes) &&
		teamRoom.abacAttributes.length > 0
	);
};

const guardABACManagedField = (room: IRoom, value: string | undefined, current: string | undefined, fieldName: string): void => {
	if (!value && !current) {
		return;
	}
	if (value === current) {
		return;
	}
	if (isABACManagedRoom(room)) {
		throw new Meteor.Error('error-action-not-allowed', `Editing an ABAC managed room's ${fieldName} is not allowed`, {
			method: 'saveRoomSettings',
			action: 'Editing_room',
		});
	}
};

const validators: RoomSettingsValidators = {
	async default({ userId, room, value }) {
		if (!(await hasPermissionAsync(userId, 'view-room-administration'))) {
			throw new Meteor.Error('error-action-not-allowed', 'Viewing room administration is not allowed', {
				method: 'saveRoomSettings',
				action: 'Viewing_room_administration',
			});
		}
		if (isABACManagedRoom(room) && value) {
			throw new Meteor.Error('error-action-not-allowed', 'Setting an ABAC managed room as default is not allowed', {
				method: 'saveRoomSettings',
				action: 'Viewing_room_administration',

View on GitHub (pinned to 2a7de45707)

Solutions

  1. Do not edit topic/announcement/description for ABAC-managed rooms in the UI or API; manage those values in the identity provider's attribute mapping instead.
  2. Make settings forms only submit changed fields (diff against current values) so unchanged or empty-but-unchanged fields do not trip the guard.
  3. If the room should no longer be ABAC-managed, clear its abacAttributes (or correct the provisioning) so local editing is allowed again.
  4. As a last resort on workspaces not using ABAC, turn off the ABAC_Enabled setting.

Example fix

// before
await Meteor.callAsync('saveRoomSettings', rid, 'roomTopic', newTopic); // ABAC room -> throws

// after
const room = Rooms.findOneById(rid, { projection: { topic: 1, t: 1, abacAttributes: 1 } });
const abacManaged = room.t === 'p' && settings.get('ABAC_Enabled') && (room.abacAttributes?.length ?? 0) > 0;
if (!abacManaged && newTopic !== room.topic) {
  await Meteor.callAsync('saveRoomSettings', rid, 'roomTopic', newTopic);
}
Defensive patterns

Strategy: validation

Validate before calling

// Only submit profile fields the ABAC policy allows to change
const room = await Rooms.findOneById(rid, { projection: { t: 1, abacAttributes: 1, topic: 1, announcement: 1, description: 1 } });
const abacManaged = room.t === 'p' && settings.get('ABAC_Enabled') && (room.abacAttributes?.length ?? 0) > 0;
const next: Record<string, string> = {};
if (!abacManaged) {
  if (topic !== room.topic) next.roomTopic = topic;
  if (announcement !== room.announcement) next.roomAnnouncement = announcement;
  if (description !== room.description) next.roomDescription = description;
}
if (Object.keys(next).length) await Meteor.callAsync('saveRoomSettings', rid, next);

Type guard

const isABACManagedRoom = (room: Pick<IRoom, 't' | 'abacAttributes'>): boolean =>
  room.t === 'p' && settings.get<boolean>('ABAC_Enabled') && Array.isArray(room.abacAttributes) && room.abacAttributes.length > 0;

Try / catch

try {
  await Meteor.callAsync('saveRoomSettings', rid, 'roomTopic', value);
} catch (err) {
  if (err instanceof Meteor.Error && err.error === 'error-action-not-allowed' && /ABAC managed/.test(err.reason ?? '')) {
    showNotice('This room is managed by your identity provider; its profile fields are read-only.');
    return;
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling Meteor.call('saveRoomSettings', rid, 'roomTopic', 'new text') on a private room created/mapped by SAML ABAC provisioning while ABAC_Enabled is true and the room has abacAttributes; same for roomAnnouncement and roomDescription; also when clearing a topic that was set by the IdP mapping.

Common situations: SAML SSO workspaces with attribute-based room provisioning; admins trying to prettify auto-provisioned rooms; UI forms that always submit all fields — submitting an empty topic for a room whose topic is IdP-managed triggers the throw even without user intent to change it.

Related errors


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