{"record":{"id":"49a1d9bace43737d","repo":"instructure/canvas-lms","slug":"permission-must-be-enabled-for-someone","errorCode":null,"errorMessage":"Permission must be enabled for someone","messagePattern":"Permission must be enabled for someone","errorType":"exception","errorClass":"BadPermissionSettingError","httpStatus":400,"severity":"error","filePath":"app/controllers/role_overrides_controller.rb","lineNumber":686,"sourceCode":"          else\n            locked = value_to_boolean(permission_updates[:locked])\n          end\n        end\n\n        if permission_updates.key?(:enabled) && value_to_boolean(permission_updates[:explicit])\n          override = value_to_boolean(permission_updates[:enabled])\n        end\n\n        if permission_updates.key? :applies_to_self\n          applies_to_self = value_to_boolean(permission_updates[:applies_to_self])\n        end\n\n        if permission_updates.key? :applies_to_descendants\n          applies_to_descendants = value_to_boolean(permission_updates[:applies_to_descendants])\n        end\n\n        if applies_to_descendants == false && applies_to_self == false\n          raise BadPermissionSettingError, t(\"Permission must be enabled for someone\")\n        end\n\n        target_permissions.each do |permission|\n          perm_override = (value_to_boolean(permission_updates[:explicit]) && override.nil?) ? permission[:currently] : override\n          RoleOverride.manage_role_override(\n            context,\n            role,\n            permission[:name].to_s,\n            override: perm_override,\n            locked:,\n            applies_to_self:,\n            applies_to_descendants:\n          )\n        end\n      end\n    end\n  end\n  protected :set_permissions_for","sourceCodeStart":668,"sourceCodeEnd":704,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/controllers/role_overrides_controller.rb#L668-L704","documentation":"A permission entry must be applicable either to the context itself or to its descendants. If the request computes applies_to_self=false and applies_to_descendants=false, there is no valid scope left, so BadPermissionSettingError is raised.","triggerScenarios":"Calling role update/add_role with permission params like {enabled: true, applies_to_self: false, applies_to_descendants: false} for a given permission.","commonSituations":"API clients mirroring UI checkboxes where both boxes are unchecked; automation setting explicit false for both flags; stale request bodies after the applies_to_* params were introduced.","solutions":["Set applies_to_self or applies_to_descendants to true (or omit one so it defaults appropriately).","Only send one of the applies_to_* flags, letting the other default.","Ensure the client form/UI enforces at least one of the two flags being true."],"exampleFix":"// before\npermissions: {manage_courses: {explicit: true, enabled: true, applies_to_self: false, applies_to_descendants: false}}\n// after\npermissions: {manage_courses: {explicit: true, enabled: true, applies_to_self: true, applies_to_descendants: false}}","handlingStrategy":"validation","validationCode":"if (p.applies_to_self === false && p.applies_to_descendants === false) throw new Error('permission must apply to self or descendants')","typeGuard":null,"tryCatchPattern":"try { await api.updateRole(roleId, body) } catch (e) { if (e.message === 'Permission must be enabled for someone') { /* coerce one flag to true or surface to user */ } else throw e }","preventionTips":["Never send both applies_to flags as false","Let UI enforce at least one enabled scope","Omit flags you do not intend to change"],"tags":["permissions","api","validation"],"backgroundTag":"conflicting-config-options","analyzedSha":"1c9f0bb8013ed69c4f2efe11fd483025469b7e6c","analyzedAt":"2026-09-15T20:33:18.891Z","contentChangedAt":"2026-09-15T20:33:18.891Z","schemaVersion":2},"datasetVersion":"2026-09-23T02:17:17.105Z"}