CanCanCommunity/cancancan · error · ArgumentError
accessible_by_strategy must be one of #{valid_accessible_by_
Error message
accessible_by_strategy must be one of #{valid_accessible_by_strategies.join(', ')} What it means
CanCan.accessible_by_strategy= validates the value via validate_accessible_by_strategy! (lib/cancan/config.rb:94) against CanCan.valid_accessible_by_strategies, which is [:left_join] plus the subquery-family strategies (:joined_alias_exists_subquery, :joined_alias_each_rule_as_exists_subquery, :subquery) only when ActiveRecord >= 5 is available. Anything else, including valid-looking values on an old Rails, raises ArgumentError.
Source
Thrown at lib/cancan/config.rb:94
def self.with_accessible_by_strategy(value)
return yield if value == accessible_by_strategy
validate_accessible_by_strategy!(value)
begin
strategy_was = accessible_by_strategy
@accessible_by_strategy = value
yield
ensure
@accessible_by_strategy = strategy_was
end
end
def self.validate_accessible_by_strategy!(value)
return if valid_accessible_by_strategies.include?(value)
raise ArgumentError, "accessible_by_strategy must be one of #{valid_accessible_by_strategies.join(', ')}"
end
def self.does_not_support_subquery_strategy?
!defined?(CanCan::ModelAdapters::ActiveRecordAdapter) ||
CanCan::ModelAdapters::ActiveRecordAdapter.version_lower?('5.0.0')
end
end
View on GitHub (pinned to 8c1bf153a3)
Solutions
- Use a value from the allowed list: check it live with puts CanCan.valid_accessible_by_strategies.
- On Rails < 5, use only :left_join.
- Derive the value defensively: CanCan.accessible_by_strategy = (ENV['STRATEGY'] || :left_join).to_sym, after confirming membership in the valid list.
Example fix
# before
CanCan.accessible_by_strategy = ENV.fetch('CANCAN_STRATEGY', :left_join) # 'subquerry' from ENV -> ArgumentError
# after
strategy = ENV.fetch('CANCAN_STRATEGY', :left_join).to_sym
CanCan.accessible_by_strategy = strategy if CanCan.valid_accessible_by_strategies.include?(strategy) Defensive patterns
Strategy: validation
Validate before calling
strategy = ENV.fetch('CANCAN_STRATEGY', :left_join).to_sym
raise ArgumentError, "invalid strategy #{strategy}; valid: #{CanCan.valid_accessible_by_strategies.join(', ')}" unless CanCan.valid_accessible_by_strategies.include?(strategy)
CanCan.accessible_by_strategy = strategy Type guard
def valid_strategy?(value) CanCan.valid_accessible_by_strategies.include?(value.to_s.to_sym) end
Try / catch
begin CanCan.accessible_by_strategy = strategy rescue ArgumentError => e raise ConfigError, e.message end
Prevention
- Never source strategy values from unvalidated config; validate against the public allow-list first.
- Use symbols, not strings, when assigning configuration in initializers.
- Log CanCan.valid_accessible_by_strategies at boot so the supported set is visible per environment.
When it happens
Trigger: Typo'd or wrong-type values: CanCan.accessible_by_strategy = :subquerry, 'subquery' (String), or :leftJoin; setting :subquery when ActiveRecord is < 5 so it is not in the valid list; passing an ad-hoc strategy to CanCan.with_accessible_by_strategy in a spec.
Common situations: Initializers drifted from a README snippet whose supported values differ across cancancan versions; environment divergence where development is on Rails 7 but a staging app pins Rails 4; string vs symbol mismatch when reading the value from ENV.
Related errors
- accessible_by_strategy = :subquery requires ActiveRecord 5 o
- You are not authorized to access this page.
- You can't specify target (#{target}) as alias because it is
- The can? and cannot? call cannot be used with a raw sql 'can
- This model adapter does not support matching on a conditions
AI-assisted analysis of CanCanCommunity/cancancan@8c1bf153a3 (2026-08-21).
Data as JSON: /api/errors/83973676849e4678.
Report an issue: GitHub.