{"record":{"id":"3d2ac631f0bd3ea3","repo":"mislav/will_paginate","slug":"invalid-name-value-inspect","errorCode":null,"errorMessage":"invalid #{name}: #{value.inspect}","messagePattern":"invalid #(.+?): #(.+?)","errorType":"exception","errorClass":"RangeError","httpStatus":null,"severity":"error","filePath":"lib/will_paginate/page_number.rb","lineNumber":17,"sourceCode":"require 'forwardable'\n\nmodule WillPaginate\n  # a module that page number exceptions are tagged with\n  module InvalidPage; end\n\n  # integer representing a page number\n  class PageNumber < Numeric\n    # a value larger than this is not supported in SQL queries\n    BIGINT = 9223372036854775807\n\n    extend Forwardable\n\n    def initialize(value, name)\n      value = Integer(value)\n      if 'offset' == name ? (value < 0 or value > BIGINT) : value < 1\n        raise RangeError, \"invalid #{name}: #{value.inspect}\"\n      end\n      @name = name\n      @value = value\n    rescue ArgumentError, TypeError, RangeError => error\n      error.extend InvalidPage\n      raise error\n    end\n\n    def to_i\n      @value\n    end\n\n    def_delegators :@value, :coerce, :==, :<=>, :to_s, :+, :-, :*, :/, :to_json\n\n    def inspect\n      \"#{@name} #{to_i}\"\n    end\n","sourceCodeStart":1,"sourceCodeEnd":35,"githubUrl":"https://github.com/mislav/will_paginate/blob/50017c3eb0712e7b3a53268a81e81a184b7a49f6/lib/will_paginate/page_number.rb#L1-L35","documentation":"WillPaginate::PageNumber coerces its input with Integer(value) and enforces a range: page numbers must be >= 1, offsets must be 0..BIGINT (2^63-1, the SQL bigint ceiling). Violations raise RangeError 'invalid page/offset: ...', and any coercion failure (ArgumentError/TypeError) is extended with the WillPaginate::InvalidPage module before re-raising, so all bad-input cases are catchable as WillPaginate::InvalidPage.","triggerScenarios":"Model.page(params[:page]) with params[:page] = 'abc' (Integer('abc') -> ArgumentError), '0' or 0 or -3 (below the minimum of 1), or a URL-crafted huge value like 99999999999999999999 (Integer works but exceeds nothing... only offsets compare to BIGINT; a page that huge is fine for page, but offset = (page-1)*per_page can exceed BIGINT and blow up in the offset branch). Also .page(1.5) style garbage from form input.","commonSituations":"Public-facing list endpoints where :page comes straight from the query string and is never sanitized; scrapers/bots probing ?page=0 or ?page=-1; user-typed junk in a search box bound to the page param; wrapping arithmetic that computes an offset overflow.","solutions":["Sanitize the param at the boundary: page = params[:page].presence && params[:page].to_i; page = nil if page && page < 1 — nil coerces to page 1 downstream","Rescue WillPaginate::InvalidPage in the controller and fall back to page 1 or render a 404","Clamp derived offsets to 0..WillPaginate::PageNumber::BIGINT before passing them to the offset API"],"exampleFix":"// before\n@posts = Post.page(params[:page])\n\n// after\nraw = params[:page].to_s\npage = raw.match?(/\\A[1-9]\\d*\\z/) ? raw.to_i : 1\n@posts = Post.page(page)","handlingStrategy":"try-catch","validationCode":"raw = params[:page].to_s\npage = raw.match?(/\\A[1-9]\\d*\\z/) ? raw.to_i : nil # nil -> page 1 downstream\npage = nil if page && page > WillPaginate::PageNumber::BIGINT\n@posts = Post.page(page)","typeGuard":"def valid_page_number?(value)\n  s = value.to_s\n  s.match?(/\\A[1-9]\\d*\\z/) && s.to_i <= WillPaginate::PageNumber::BIGINT\nend","tryCatchPattern":"begin\n  @posts = Post.page(params[:page]).per(10)\nrescue WillPaginate::InvalidPage # RangeError/ArgumentError/TypeError tagged by PageNumber\n  redirect_to(posts_path(page: 1)) and return # or render plain: 'Not Found', status: 404\nend","preventionTips":["Sanitize :page once in a controller concern: digits-only, >= 1, capped at a sane ceiling (e.g. 10_000), nil otherwise","Never pass params[:page] straight into page()/paginate() on public endpoints — bots routinely probe ?page=0 and junk","Rescue WillPaginate::InvalidPage globally in a controller around_action to render 404 instead of a 500"],"tags":["will-paginate","range-error","user-input","pagination"],"backgroundTag":"invalid-page-number","analyzedSha":"50017c3eb0712e7b3a53268a81e81a184b7a49f6","analyzedAt":"2026-08-21T19:50:58.546Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}