CanCanCommunity/cancancan · error · CanCan::Error

Subject is required for #{action}

Error message

Subject is required for #{action}

What it means

Rule#initialize (lib/cancan/rule.rb:28) requires a subject whenever an action is given: raise Error, "Subject is required for #{action}" if action && subject.nil?. The only subject-less form allowed is the fully bare can/cannot (action and subject both nil), which becomes a match-all rule; an action without a subject is almost always a truncated can call or a nil variable.

Source

Thrown at lib/cancan/rule.rb:28

  # helpful methods to determine permission checking and conditions hash generation.
  class Rule # :nodoc:
    include ConditionsMatcher
    include Relevant
    include ParameterValidators
    attr_reader :base_behavior, :subjects, :actions, :conditions, :attributes, :block
    attr_writer :expanded_actions, :conditions

    # The first argument when initializing is the base_behavior which is a true/false
    # value. True for "can" and false for "cannot". The next two arguments are the action
    # and subject respectively (such as :read, @project). The third argument is a hash
    # of conditions and the last one is the block passed to the "can" call.
    def initialize(base_behavior, action, subject, *extra_args, &block)
      # for backwards compatibility, attributes are an optional parameter. Check if
      # attributes were passed or are actually conditions
      attributes, extra_args = parse_attributes_from_extra_args(extra_args)
      condition_and_block_check(extra_args, block, action, subject)
      @match_all = action.nil? && subject.nil?
      raise Error, "Subject is required for #{action}" if action && subject.nil?

      @base_behavior = base_behavior
      @actions = wrap(action)
      @subjects = wrap(subject)
      @attributes = wrap(attributes)
      @conditions = extra_args || {}
      @block = block
    end

    def inspect
      repr = "#<#{self.class.name}"
      repr += "#{@base_behavior ? 'can' : 'cannot'} #{@actions.inspect}, #{@subjects.inspect}, #{@attributes.inspect}"

      if with_scope?
        repr += ", #{@conditions.where_values_hash}"
      elsif [Hash, String].include?(@conditions.class)
        repr += ", #{@conditions.inspect}"
      end

View on GitHub (pinned to 8c1bf153a3)

Solutions

  1. Add the subject: can :read, Article, or for everything can :read, :all.
  2. For non-model pages use a symbol namespace: can :read, :dashboard.
  3. Guard nil subjects before defining rules: only define the rule when the subject variable is present.

Example fix

# before
can :read                # CanCan::Error: Subject is required for read
can :read, maybe_project # maybe_project nil at definition time

# after
can :read, :all
can :read, Project if maybe_project  # or restructure so the subject is never nil
Defensive patterns

Strategy: validation

Validate before calling

# central guarded definition helper in the Ability
def define_ability(action, subject = nil, **conditions, &block)
  raise ArgumentError, "Subject is required for #{action}" if action && subject.nil?
  can(action, subject || :all, **conditions, &block)
end

Type guard

def complete_rule?(action, subject)
  action.nil? || !subject.nil?
end

Try / catch

begin
  can :read, subject_var
rescue CanCan::Error => e
  Rails.logger.error("bad ability definition: #{e.message}")
  raise # definition bugs must surface at boot, not be swallowed
end

Prevention

When it happens

Trigger: can :read with no second argument; cannot :delete; a subject variable that evaluates to nil at rule-definition time (can :read, @project inside an ability built before @project exists); passing nil explicitly via can :read, nil.

Common situations: Copy-paste truncation of an ability line; abilities built with variables that can be nil (conditional subjects); refactoring that renames a variable to nil in some branch.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of CanCanCommunity/cancancan@8c1bf153a3 (2026-08-21). Data as JSON: /api/errors/c7f827ec6e463cf2. Report an issue: GitHub.