padrino/padrino-framework · error · Padrino::Admin::AccessControlError
You can't merge :any with other roles
Error message
You can't merge :any with other roles
What it means
roles_for refuses to combine the special role :any with concrete roles. :any already matches every account, so merging it with :admin would make it ambiguous which authorization block governs a request. Give :any its own single-role block, or list only concrete roles.
Source
Thrown at padrino-admin/lib/padrino-admin/access_control.rb:48
app.send(:access_control=, Padrino::Admin::AccessControl::Base.new)
end
alias included registered
end
##
# This base access control class where roles are defined as are authorizations.
#
class Base
def initialize
@roles, @authorizations, @project_modules = [], [], []
end
##
# We map project modules for a given role or roles.
#
def roles_for(*roles, &block)
raise Padrino::Admin::AccessControlError, "Role #{role} must be present and must be a symbol!" if roles.any? { |r| !r.is_a?(Symbol) } || roles.empty?
raise Padrino::Admin::AccessControlError, "You can't merge :any with other roles" if roles.size > 1 && roles.any? { |r| r == :any }
@roles += roles
@authorizations << Authorization.new(*roles, &block)
end
##
# Return an array of roles.
#
def roles
@roles.uniq.reject { |r| r == :any }
end
##
# Return an array of project_modules.
#
def project_modules(account)
role = account.role.to_sym rescue :any
authorizations = @authorizations.find_all { |auth| auth.roles.include?(role) }View on GitHub (pinned to 167044f3d5)
Solutions
- Split into two blocks: roles_for(:any) { ... } and roles_for(:admin) { ... }
- If :any was unintended, remove it and keep only the concrete roles
- When building role lists dynamically, reject :any first (roles.reject { |r| r == :any }) or assert it is the sole entry before calling roles_for
Example fix
# before access_control.roles_for(:any, :admin) do |role| ... end # after access_control.roles_for(:any) do |role| ... end access_control.roles_for(:admin) do |role| ... end
Defensive patterns
Strategy: validation
Validate before calling
roles = roles.map(&:to_sym)
roles = roles.reject { |r| r == :any } unless roles == [:any]
access_control.roles_for(*roles) { |role| ... } Type guard
def any_merge_safe?(*roles) = roles.size == 1 || !roles.include?(:any)
Prevention
- Keep :any in its own roles_for(:any) block, separate from concrete roles
- Filter stored role lists for :any before splatting them into roles_for
- Remember :any already matches every account — combining it buys nothing
When it happens
Trigger: roles_for(:any, :admin); splatting an array that contains :any together with other roles (e.g. [:any] + stored_roles); refactoring a role list and leaving a stray :any in place.
Common situations: Trying to express 'admins plus everyone else'; iterating stored role records where one entry is 'any'; copy-pasting an existing roles_for block and appending :any.
Related errors
- Role #{role} must be present and must be a symbol!
- Adapter #{orm} is not yet supported!
- You must define an #{settings.admin_model} Model
- Popover requires tooltip.js
- <= At the moment, Padrino only supports #{supported_orm.join
AI-assisted analysis of padrino/padrino-framework@167044f3d5 (2026-08-23).
Data as JSON: /api/errors/df933d75590b3fd1.
Report an issue: GitHub.