{"record":{"id":"befb9a63589c84dd","repo":"RocketChat/Rocket.Chat","slug":"error-action-not-allowed-befb9a","errorCode":"error-action-not-allowed","errorMessage":"Editing an ABAC managed room's ${fieldName} is not allowed","messagePattern":"Editing an ABAC managed room's (.+?) is not allowed","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/meteor-methods/rooms/saveRoomSettings.ts","lineNumber":85,"sourceCode":"\nconst isAbacManagedTeam = (team: Partial<ITeam> | null, teamRoom: IRoom): boolean => {\n\treturn (\n\t\tteam?.type === TeamType.PRIVATE &&\n\t\tsettings.get<boolean>('ABAC_Enabled') &&\n\t\tArray.isArray(teamRoom?.abacAttributes) &&\n\t\tteamRoom.abacAttributes.length > 0\n\t);\n};\n\nconst guardABACManagedField = (room: IRoom, value: string | undefined, current: string | undefined, fieldName: string): void => {\n\tif (!value && !current) {\n\t\treturn;\n\t}\n\tif (value === current) {\n\t\treturn;\n\t}\n\tif (isABACManagedRoom(room)) {\n\t\tthrow new Meteor.Error('error-action-not-allowed', `Editing an ABAC managed room's ${fieldName} is not allowed`, {\n\t\t\tmethod: 'saveRoomSettings',\n\t\t\taction: 'Editing_room',\n\t\t});\n\t}\n};\n\nconst validators: RoomSettingsValidators = {\n\tasync default({ userId, room, value }) {\n\t\tif (!(await hasPermissionAsync(userId, 'view-room-administration'))) {\n\t\t\tthrow new Meteor.Error('error-action-not-allowed', 'Viewing room administration is not allowed', {\n\t\t\t\tmethod: 'saveRoomSettings',\n\t\t\t\taction: 'Viewing_room_administration',\n\t\t\t});\n\t\t}\n\t\tif (isABACManagedRoom(room) && value) {\n\t\t\tthrow new Meteor.Error('error-action-not-allowed', 'Setting an ABAC managed room as default is not allowed', {\n\t\t\t\tmethod: 'saveRoomSettings',\n\t\t\t\taction: 'Viewing_room_administration',","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/2a7de457074cbb4d4373fbd9a4e5bea292c9c764/apps/meteor/server/meteor-methods/rooms/saveRoomSettings.ts#L67-L103","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","solutions":["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.","Make settings forms only submit changed fields (diff against current values) so unchanged or empty-but-unchanged fields do not trip the guard.","If the room should no longer be ABAC-managed, clear its abacAttributes (or correct the provisioning) so local editing is allowed again.","As a last resort on workspaces not using ABAC, turn off the ABAC_Enabled setting."],"exampleFix":"// before\nawait Meteor.callAsync('saveRoomSettings', rid, 'roomTopic', newTopic); // ABAC room -> throws\n\n// after\nconst room = Rooms.findOneById(rid, { projection: { topic: 1, t: 1, abacAttributes: 1 } });\nconst abacManaged = room.t === 'p' && settings.get('ABAC_Enabled') && (room.abacAttributes?.length ?? 0) > 0;\nif (!abacManaged && newTopic !== room.topic) {\n  await Meteor.callAsync('saveRoomSettings', rid, 'roomTopic', newTopic);\n}","handlingStrategy":"validation","validationCode":"// Only submit profile fields the ABAC policy allows to change\nconst room = await Rooms.findOneById(rid, { projection: { t: 1, abacAttributes: 1, topic: 1, announcement: 1, description: 1 } });\nconst abacManaged = room.t === 'p' && settings.get('ABAC_Enabled') && (room.abacAttributes?.length ?? 0) > 0;\nconst next: Record<string, string> = {};\nif (!abacManaged) {\n  if (topic !== room.topic) next.roomTopic = topic;\n  if (announcement !== room.announcement) next.roomAnnouncement = announcement;\n  if (description !== room.description) next.roomDescription = description;\n}\nif (Object.keys(next).length) await Meteor.callAsync('saveRoomSettings', rid, next);","typeGuard":"const isABACManagedRoom = (room: Pick<IRoom, 't' | 'abacAttributes'>): boolean =>\n  room.t === 'p' && settings.get<boolean>('ABAC_Enabled') && Array.isArray(room.abacAttributes) && room.abacAttributes.length > 0;","tryCatchPattern":"try {\n  await Meteor.callAsync('saveRoomSettings', rid, 'roomTopic', value);\n} catch (err) {\n  if (err instanceof Meteor.Error && err.error === 'error-action-not-allowed' && /ABAC managed/.test(err.reason ?? '')) {\n    showNotice('This room is managed by your identity provider; its profile fields are read-only.');\n    return;\n  }\n  throw err;\n}","preventionTips":["Detect ABAC-managed rooms in the UI and render their topic/announcement/description as read-only.","Diff against current values and submit only changed fields, so no-op edits never trip the guard.","Manage ABAC room profile fields in the IdP attribute mapping, never via saveRoomSettings.","Remember clearing an IdP-set field counts as a change and is also blocked."],"tags":["rocket-chat","abac","saml","room-settings","guard"],"backgroundTag":"abac-managed-resource","analyzedSha":"2a7de457074cbb4d4373fbd9a4e5bea292c9c764","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}