mislav/will_paginate · error · ArgumentError

:page parameter required

Error message

:page parameter required

What it means

ActiveRecord::Relation#paginate (the Pagination module that will_paginate mixes into models/relations) requires a :page key in its options hash. The implementation calls options.fetch(:page) with a raise-on-missing block, so ArgumentError ':page parameter required' is thrown the moment the :page key is absent. It is the library's way of refusing to build a paged relation when the caller never said which page to load.

Source

Thrown at lib/will_paginate/active_record.rb:145

            col.replace super
            col.total_entries ||= total_entries
          end
        end
      end

      private

      def copy_will_paginate_data(other)
        other.current_page = current_page unless other.current_page
        other.total_entries = nil if defined? @total_entries_queried
        other
      end
    end

    module Pagination
      def paginate(options)
        options  = options.dup
        pagenum  = options.fetch(:page) { raise ArgumentError, ":page parameter required" }
        options.delete(:page)
        per_page = options.delete(:per_page) || self.per_page
        total    = options.delete(:total_entries)

        if options.any?
          raise ArgumentError, "unsupported parameters: %p" % options.keys
        end

        rel = limit(per_page.to_i).page(pagenum)
        rel.total_entries = total.to_i          unless total.blank?
        rel
      end

      def page(num)
        rel = if ::ActiveRecord::Relation === self
          self
        elsif !defined?(::ActiveRecord::Scoping) or ::ActiveRecord::Scoping::ClassMethods.method_defined? :with_scope
          # Active Record 3

View on GitHub (pinned to 50017c3eb0)

Solutions

  1. Pass an explicit page with a sane default: Model.paginate(page: params[:page] || 1, per_page: 10)
  2. Prefer the scope chain instead: Model.page(params[:page] || 1).per(10) — the page() scope never raises on a missing argument the way paginate() does
  3. If you never intended pagination, drop paginate and use limit/where directly

Example fix

// before
@posts = Post.paginate(per_page: 10)

// after
@posts = Post.paginate(page: params[:page] || 1, per_page: 10)
Defensive patterns

Strategy: validation

Validate before calling

# before calling paginate, guarantee the :page key exists with a default
opts = { page: 1 }.merge(options.symbolize_keys)
raise ArgumentError, ':page parameter required' unless opts.key?(:page)
@posts = Post.where(...).paginate(opts)

Try / catch

begin
  @posts = Post.paginate(options)
rescue ArgumentError => e
  raise unless e.message == ':page parameter required'
  @posts = Post.paginate(options.merge(page: 1))
end

Prevention

When it happens

Trigger: Calling Model.paginate(per_page: 10), Model.paginate(:per_page => 10, :total_entries => 42), or relation.paginate(...) with no :page key at all. Note the asymmetry: paginate(page: nil) does NOT raise here (nil is later coerced to page 1 by the page scope); only key absence triggers it.

Common situations: Porting old AR2-era sample code that relied on a default page; forwarding a params hash that was sliced/excepted and lost :page; test/spec helpers that call paginate directly without page; refactoring away from Model.page(num) and forgetting the option lives inside the paginate hash.

Understand the failure class

Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.

Related errors


AI-assisted analysis of mislav/will_paginate@50017c3eb0 (2026-08-21). Data as JSON: /api/errors/2f0399918719759e. Report an issue: GitHub.