docusealco/docuseal · error · Pdfium::PdfiumError

Failed to reload page #{page_index}

Error message

Failed to reload page #{page_index}

What it means

Raised by Pdfium::Page#reload (lib/pdfium.rb:1807) when FPDF_LoadPage returns NULL after the old page handle was already closed with FPDF_ClosePage. reload is called internally after successful flatten and rotate, so this error means the page became unopenable mid-operation: the parent document handle is closed/freed, the in-memory document was corrupted by the preceding mutation, or the page index no longer resolves. Because the old handle is already destroyed, the page object is unusable after this raise.

Source

Thrown at lib/pdfium.rb:1807

      if result == Pdfium::FLATTEN_FAIL
        Pdfium.check_last_error("Failed to flatten page #{page_index}")

        raise PdfiumError, "Failed to flatten page #{page_index}"
      end

      reload if result == Pdfium::FLATTEN_SUCCESS

      result
    end

    def reload
      close_page_view
      Pdfium.FPDF_ClosePage(@page_ptr)

      @page_ptr = Pdfium.FPDF_LoadPage(@document.document_ptr, @page_index)

      raise PdfiumError, "Failed to reload page #{page_index}" if @page_ptr.null?

      @page_view = false
      @rotation = nil
      @width = nil
      @height = nil
      @box = nil

      @document.reset_annot_count(@page_index)

      reset_memoization
    end

    def close
      return if closed?

      unless @page_ptr.null?
        close_page_view

View on GitHub (pinned to 004a22c1c8)

Solutions

  1. Process a document (and its pages) from a single thread; never share Pdfium::Document/Page handles across threads.
  2. Rescue PdfiumError from flatten/rotate, then rebuild from scratch: close the document, re-load it from the original bytes, and return the fresh page instead of the poisoned one.
  3. Keep a reference to the source buffer for the whole document lifetime so the in-memory document stays valid through reload.
  4. If it reproduces on one specific file, extract that page into a standalone PDF and re-run to isolate a corrupt page tree.

Example fix

# before
page.flatten
page.text_objects

# after
begin
  page.flatten
rescue Pdfium::PdfiumError
  doc = Pdfium.open_document(original_bytes)
  page = doc.page(page.index) # fresh handles after failed reload
end
page.text_objects
Defensive patterns

Strategy: fallback

Validate before calling

# Before mutating (flatten/rotate), confirm the document handle is still open
raise ArgumentError, 'document closed' if document.closed?

Try / catch

begin
  page.flatten # may internally reload
rescue Pdfium::PdfiumError
  # old page handle is destroyed after a failed reload — rebuild from source
  document.close
  document = Pdfium.open(original_bytes)
  page = document.page(index)
end

Prevention

When it happens

Trigger: reload triggered by a successful flatten/rotate while another thread called close on the document or page (concurrent access to the FFI handle); in-memory PDF buffer freed (source_buffer garbage collected on the Document) before reload; document dictionary damaged by the transform so FPDF_LoadPage rejects the page; @page_index out of range after document mutation.

Common situations: Multi-threaded PDF processing where pages of one document are shared across threads (PDFium handles are not thread-safe); long-running jobs that flatten many pages while a watchdog closes the document on timeout; rare PDFs whose page tree breaks after TransFormWithClip.

Related errors


AI-assisted analysis of docusealco/docuseal@004a22c1c8 (2026-08-21). Data as JSON: /api/errors/4f375d5176d3625c. Report an issue: GitHub.