{"record":{"id":"5569ef5d7323fb81","repo":"CanCanCommunity/cancancan","slug":"you-are-not-authorized-to-access-this-page","errorCode":null,"errorMessage":"You are not authorized to access this page.","messagePattern":"You are not authorized to access this page\\.","errorType":"exception","errorClass":"CanCan::AccessDenied","httpStatus":null,"severity":"error","filePath":"lib/cancan/ability.rb","lineNumber":180,"sourceCode":"    end\n\n    # User shouldn't specify targets with names of real actions or it will cause Seg fault\n    def validate_target(target)\n      error_message = \"You can't specify target (#{target}) as alias because it is real action name\"\n      raise Error, error_message if aliased_actions.values.flatten.include? target\n    end\n\n    def model_adapter(model_class, action)\n      adapter_class = ModelAdapters::AbstractAdapter.adapter_class(model_class)\n      adapter_class.new(model_class, relevant_rules_for_query(action, model_class))\n    end\n\n    # See ControllerAdditions#authorize! for documentation.\n    def authorize!(action, subject, *args)\n      message = args.last.is_a?(Hash) && args.last.key?(:message) ? args.pop[:message] : nil\n      if cannot?(action, subject, *args)\n        message ||= unauthorized_message(action, subject)\n        raise AccessDenied.new(message, action, subject, args)\n      end\n      subject\n    end\n\n    def attributes_for(action, subject)\n      attributes = {}\n      relevant_rules(action, subject).map do |rule|\n        attributes.merge!(rule.attributes_from_conditions) if rule.base_behavior\n      end\n      attributes\n    end\n\n    def has_block?(action, subject)\n      relevant_rules(action, subject).any?(&:only_block?)\n    end\n\n    def has_raw_sql?(action, subject)\n      relevant_rules(action, subject).any?(&:only_raw_sql?)","sourceCodeStart":162,"sourceCodeEnd":198,"githubUrl":"https://github.com/CanCanCommunity/cancancan/blob/8c1bf153a3da7b2261d6fa4a5f84eb28e2feb828/lib/cancan/ability.rb#L162-L198","documentation":"This is CanCanCan's core authorization failure: Ability#authorize! (lib/cancan/ability.rb:180) raises CanCan::AccessDenied when cannot?(action, subject) is true. The generic 'You are not authorized to access this page.' text is used when no custom :message was passed and no unauthorized_message/i18n entry resolved. The raised exception carries action, subject, and conditions accessors, so you can inspect exactly which check failed.","triggerScenarios":"Calling authorize! :edit, @article when the current ability has no matching 'can' rule; load_and_authorize_resource on a controller action whose rules deny access (e.g., a role Ability missing can :manage, Article); a rule whose condition hash or block evaluates false for that specific record.","commonSituations":"Forgot can :manage, :all for admin users; conditions hash key not matching record attributes (e.g., owner_id vs user_id); Devise session expired so current_user is nil and the default Ability denies everything; abilities defined per-role but the role column returned an unexpected value; nested or :through resources failing the parent check.","solutions":["Handle the exception globally: rescue_from CanCan::AccessDenied in ApplicationController and redirect or render 403.","Add or fix the ability rule in app/models/ability.rb (e.g., can :manage, Article for the failing role), using the exception's action/subject to pinpoint it.","Verify the ability wiring: current_user is set, the correct Ability class (Ability.new(current_user)) is used, and rule conditions match real column names.","Pass a custom message (authorize! :edit, @article, message: '...') or add i18n entries under unauthorized_message for clearer UX."],"exampleFix":"# before (app/models/ability.rb)\nclass Ability\n  include CanCan::Ability\n  def initialize(user)\n    can :read, Article\n    # no rule for :edit -> authorize! :edit raises AccessDenied\n  end\nend\n\n# after\nclass Ability\n  include CanCan::Ability\n  def initialize(user)\n    return unless user\n    can :manage, Article, owner_id: user.id\n    can :read, Article\n  end\nend\n\n# app/controllers/application_controller.rb\nclass ApplicationController < ActionController::Base\n  rescue_from CanCan::AccessDenied do |exception|\n    redirect_to root_path, alert: exception.message\n  end\nend","handlingStrategy":"try-catch","validationCode":"# guard before authorizing (e.g., for soft-gated UI instead of an exception)\nreturn render_forbidden unless current_ability.can?(:edit, @article)","typeGuard":"def access_denied?(exception)\n  exception.is_a?(CanCan::AccessDenied)\nend","tryCatchPattern":"# app/controllers/application_controller.rb\nclass ApplicationController < ActionController::Base\n  rescue_from CanCan::AccessDenied do |exception|\n    Rails.logger.warn(\"ACCESS DENIED: #{exception.action} on #{exception.subject.inspect}\")\n    respond_to do |format|\n      format.json { render json: { error: 'Forbidden' }, status: :forbidden }\n      format.html { redirect_to root_path, alert: exception.message }\n    end\n  end\nend","preventionTips":["Use load_and_authorize_resource instead of hand-rolled authorize! calls so no action forgets the check.","Cover every Ability with request specs asserting can?/cannot? for each role, using the be_able_to matcher.","Log exception.action and exception.subject in the rescue block to pinpoint the missing rule fast.","Instantiate the Ability with the real user object and fail closed (deny all) when user is nil."],"tags":["authorization","access-denied","cancancan","ruby","rails"],"backgroundTag":"authorization-denied","analyzedSha":"8c1bf153a3da7b2261d6fa4a5f84eb28e2feb828","analyzedAt":"2026-08-21T20:05:55.000Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}