{"record":{"id":"ba9ee4c32b38dd07","repo":"docusealco/docuseal","slug":"page-index-page-index-out-of-range-0-page-c","errorCode":null,"errorMessage":"Page index #{page_index} out of range (0..#{page_count - 1})","messagePattern":"Page index #(.+?) out of range \\(0\\.\\.#(.+?)\\)","errorType":"exception","errorClass":"Pdfium::PdfiumError","httpStatus":null,"severity":"error","filePath":"lib/pdfium.rb","lineNumber":700,"sourceCode":"        yield doc\n      ensure\n        doc.close\n      end\n    end\n\n    def closed?\n      @closed\n    end\n\n    def ensure_not_closed!\n      raise PdfiumError, 'Document is closed.' if closed?\n    end\n\n    def get_page(page_index)\n      ensure_not_closed!\n\n      unless page_index.is_a?(Integer) && page_index >= 0 && page_index < page_count\n        raise PdfiumError, \"Page index #{page_index} out of range (0..#{page_count - 1})\"\n      end\n\n      @pages[page_index] ||= Page.new(self, page_index)\n    end\n\n    def bookmarks(parent = nil, seen = Set.new)\n      acc = []\n      bookmark = Pdfium.FPDFBookmark_GetFirstChild(@document_ptr, parent)\n\n      until bookmark.null?\n        break unless seen.add?(bookmark.address)\n\n        acc << [bookmark_title(bookmark), *destination(Pdfium.FPDFBookmark_GetDest(@document_ptr, bookmark))]\n        acc.concat(bookmarks(bookmark, seen))\n\n        bookmark = Pdfium.FPDFBookmark_GetNextSibling(@document_ptr, bookmark)\n      end\n","sourceCodeStart":682,"sourceCodeEnd":718,"githubUrl":"https://github.com/docusealco/docuseal/blob/004a22c1c88109c7ba0b567df011a8cb13894001/lib/pdfium.rb#L682-L718","documentation":"Validation guard in Document#get_page: the index must be an Integer, greater than or equal to 0, and strictly less than page_count. It fires for negative indexes, indexes at or above page_count, and non-Integer inputs such as nil, strings, or floats. The message includes the valid range (0..page_count-1), which makes off-by-one mistakes (1-based user input vs 0-based API) easy to spot.","triggerScenarios":"get_page(page_count) when targeting the last page (1-based input not converted); get_page(-1); get_page(params[:page]) where the param is the String '2' or nil; a stale page_count assumption after import_pages changed the document.","commonSituations":"User-facing page numbers are 1-based while this API is 0-based; JSON request params arriving as strings; iterating 1..page_count instead of 0...page_count.","solutions":["Convert and normalize input: idx = Integer(params[:page]) rescue 0, then subtract 1 if the input is 1-based","Always go through doc.get_page(idx), which validates, instead of constructing Pdfium::Page directly","Re-read doc.page_count after document mutations (import_pages resets the memoized count) before indexing"],"exampleFix":"# before\npage = doc.get_page(params[:page]) # String '2' or 1-based input raises\n\n# after\nidx = Integer(params[:page], 10) rescue 0\nidx -= 1 if params[:one_based]\nidx = idx.clamp(0, doc.page_count - 1)\npage = doc.get_page(idx)","handlingStrategy":"validation","validationCode":"def valid_page_index?(doc, idx)\n  idx.is_a?(Integer) && idx >= 0 && idx < doc.page_count\nend\n\nraise ArgumentError, 'page out of range' unless valid_page_index?(doc, idx)","typeGuard":"def integer_page_index?(value)\n  value.is_a?(Integer) && value >= 0\nend","tryCatchPattern":"begin\n  page = doc.get_page(idx)\nrescue Pdfium::PdfiumError => e\n  raise unless e.message.start_with?('Page index ')\n  idx = idx.clamp(0, doc.page_count - 1)\n  retry\nend","preventionTips":["Convert request params with Integer() at the boundary; never pass raw strings to get_page","Translate 1-based user page numbers to 0-based indexes in one place","Re-read page_count after import_pages; the memoized count resets"],"tags":["pdfium","pagination","index-validation","ruby"],"backgroundTag":"index-out-of-bounds","analyzedSha":"004a22c1c88109c7ba0b567df011a8cb13894001","analyzedAt":"2026-08-21T13:38:23.343Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}