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 3View on GitHub (pinned to 50017c3eb0)
Solutions
- Pass an explicit page with a sane default: Model.paginate(page: params[:page] || 1, per_page: 10)
- 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
- 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
- Centralize pagination params in one controller helper: def page_param = params[:page] || 1, and use it at every paginate call site
- Prefer the page(...).per(...) scope chain over paginate in new code — it degrades gracefully on nil/missing page
- Add a spec that exercises each list action with an empty params hash to catch missing :page before production
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
- unsupported parameters: %p
- invalid #{name}: #{value.inspect}
- :renderer not specified
- The #{collection_name} variable appears to be empty. Did you
- DEPRECATION WARNING: #{message} (called from #{offending_lin
AI-assisted analysis of mislav/will_paginate@50017c3eb0 (2026-08-21).
Data as JSON: /api/errors/2f0399918719759e.
Report an issue: GitHub.