instructure/canvas-lms · error · BadPermissionSettingError

Permission must be enabled for someone

Error message

Permission must be enabled for someone

What it means

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.

Solutions

  1. Set applies_to_self or applies_to_descendants to true (or omit one so it defaults appropriately).
  2. Only send one of the applies_to_* flags, letting the other default.
  3. Ensure the client form/UI enforces at least one of the two flags being true.

Example fix

// before
permissions: {manage_courses: {explicit: true, enabled: true, applies_to_self: false, applies_to_descendants: false}}
// after
permissions: {manage_courses: {explicit: true, enabled: true, applies_to_self: true, applies_to_descendants: false}}
Defensive patterns

Strategy: validation

Validate before calling

if (p.applies_to_self === false && p.applies_to_descendants === false) throw new Error('permission must apply to self or descendants')

Try / catch

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 }

Prevention

When it happens

Trigger: Calling role update/add_role with permission params like {enabled: true, applies_to_self: false, applies_to_descendants: false} for a given permission.

Common situations: 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.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15). Data as JSON: /api/errors/49a1d9bace43737d. Report an issue: GitHub.

Appendix: source

Thrown at app/controllers/role_overrides_controller.rb:686

          else
            locked = value_to_boolean(permission_updates[:locked])
          end
        end

        if permission_updates.key?(:enabled) && value_to_boolean(permission_updates[:explicit])
          override = value_to_boolean(permission_updates[:enabled])
        end

        if permission_updates.key? :applies_to_self
          applies_to_self = value_to_boolean(permission_updates[:applies_to_self])
        end

        if permission_updates.key? :applies_to_descendants
          applies_to_descendants = value_to_boolean(permission_updates[:applies_to_descendants])
        end

        if applies_to_descendants == false && applies_to_self == false
          raise BadPermissionSettingError, t("Permission must be enabled for someone")
        end

        target_permissions.each do |permission|
          perm_override = (value_to_boolean(permission_updates[:explicit]) && override.nil?) ? permission[:currently] : override
          RoleOverride.manage_role_override(
            context,
            role,
            permission[:name].to_s,
            override: perm_override,
            locked:,
            applies_to_self:,
            applies_to_descendants:
          )
        end
      end
    end
  end
  protected :set_permissions_for

View on GitHub (pinned to 1c9f0bb801)