docusealco/docuseal · error · Pdfium::PdfiumError

Failed to unwrap form object

Error message

Failed to unwrap form object

What it means

Raised in Page#unwrap_form_objects when FPDFFormObj_RemoveObject returns 0 while detaching a child object from a form object during redact or flatten. There is no check_last_error; the zero return means pdfium refused the removal, typically for malformed or deeply nested form XObject trees. The loop retries until no intersecting form object remains, so this fires on structural edge cases rather than ordinary AcroForm flattening.

Source

Thrown at lib/pdfium.rb:1256

        form_ptr = find_form_object(rect_bounds)

        break if form_ptr.nil?

        unwrapped = true

        matrix =
          if Pdfium.FPDFPageObj_GetMatrix(form_ptr, matrix_ptr).zero?
            [1.0, 0.0, 0.0, 1.0, 0.0, 0.0]
          else
            matrix_ptr.read_array_of_float(6)
          end

        (Pdfium.FPDFFormObj_CountObjects(form_ptr) - 1).downto(0) do |index|
          child_ptr = Pdfium.FPDFFormObj_GetObject(form_ptr, index)

          next if child_ptr.null?

          raise PdfiumError, 'Failed to unwrap form object' if Pdfium.FPDFFormObj_RemoveObject(form_ptr,
                                                                                               child_ptr).zero?

          Pdfium.FPDFPageObj_Transform(child_ptr, *matrix)
          Pdfium.FPDFPage_InsertObject(@page_ptr, child_ptr)
        end

        remove_page_object(form_ptr)
      end

      Pdfium.FPDFPage_GenerateContent(@page_ptr) if unwrapped

      reset_memoization if unwrapped
    end

    def find_form_object(rect_bounds = nil)
      bounds_ptrs = Array.new(4) { FFI::MemoryPointer.new(:float) }

      Pdfium.FPDFPage_CountObjects(@page_ptr).times do |index|

View on GitHub (pinned to 004a22c1c8)

Solutions

  1. Catch per page and fall back to draw-only redaction (opaque rects without form unwrapping)
  2. Update libpdfium; the form-object APIs gained robustness across releases
  3. Pre-flatten the PDF with another tool (ghostscript) and then redact
  4. In batch pipelines, skip and report the page for manual redaction

Example fix

# before
page.redact(rects)

# after
begin
  page.redact(rects)
rescue Pdfium::PdfiumError => e
  raise unless e.message == 'Failed to unwrap form object'
  page.draw_only_redact(rects) # fallback: paint rects, skip unwrapping
end
Defensive patterns

Strategy: fallback

Try / catch

begin
  page.redact(rects)
rescue Pdfium::PdfiumError => e
  raise unless e.message == 'Failed to unwrap form object'
  page_redact_draw_only(page, rects) # opaque rects without form flattening
end

Prevention

When it happens

Trigger: redact on pages containing nested form XObjects (forms inside forms), XFA remnants, or form objects with broken internal object arrays; PDFs from generators that wrap content in unusual XObject nesting.

Common situations: Flattening and redacting government/tax forms; PDFs printed through virtual printers that wrap page content in form XObjects.

Related errors


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