docusealco/docuseal · error · Pdfium::PdfiumError

Failed to create redaction rect

Error message

Failed to create redaction rect

What it means

Raised in draw_redaction_rects when FPDFPageObj_CreateNewRect returns NULL for the computed left/bottom/width/height. CreateNewRect fails for degenerate geometry (zero or negative width/height), which happens when an input rect's w or h rounds to zero after the x*width / height - y*height coordinate math, or under memory exhaustion. Rects with color 'white' are skipped earlier, so only colored rects reach this call.

Source

Thrown at lib/pdfium.rb:1407

      @text_objects = nil
      @line_nodes = nil
      @annotations = nil
      @objects = nil
    end

    def remove_page_object(object_ptr)
      raise PdfiumError, 'Failed to remove page object' if Pdfium.FPDFPage_RemoveObject(@page_ptr, object_ptr).zero?

      Pdfium.FPDFPageObj_Destroy(object_ptr)
    end

    def draw_redaction_rects(rect_bounds)
      rect_bounds.each do |left, bottom, right, top, color|
        next if color == 'white'

        rect_object = Pdfium.FPDFPageObj_CreateNewRect(left, bottom, right - left, top - bottom)

        raise PdfiumError, 'Failed to create redaction rect' if rect_object.null?

        Pdfium.FPDFPageObj_SetFillColor(rect_object, 0, 0, 0, 255)
        Pdfium.FPDFPath_SetDrawMode(rect_object, 1, 0)
        Pdfium.FPDFPage_InsertObject(@page_ptr, rect_object)
      end
    end

    def redact_image_objects(rect_bounds)
      bounds_ptrs = Array.new(4) { FFI::MemoryPointer.new(:float) }
      matrix_ptr = FFI::MemoryPointer.new(:float, 6)

      Pdfium.FPDFPage_CountObjects(@page_ptr).times do |index|
        object_ptr = Pdfium.FPDFPage_GetObject(@page_ptr, index)

        next if object_ptr.null?
        next unless Pdfium.FPDFPageObj_GetType(object_ptr) == FPDF_PAGEOBJ_IMAGE
        next if Pdfium.FPDFPageObj_GetBounds(object_ptr, *bounds_ptrs).zero?

View on GitHub (pinned to 004a22c1c8)

Solutions

  1. Validate redaction input: require rect['w'].to_f > 0 and rect['h'].to_f > 0 before calling redact
  2. Filter degenerate rects out of the batch instead of failing the whole page
  3. Reject non-numeric or missing w/h at the API boundary rather than coercing nil to 0

Example fix

# before
page.redact(all_rects)

# after
page.redact(all_rects.select { |r| r['w'].to_f.positive? && r['h'].to_f.positive? })
Defensive patterns

Strategy: validation

Validate before calling

def sane_redaction_rects?(rects)
  rects.all? { |r| %w[x y w h].all? { |k| r[k].is_a?(Numeric) } && r['w'].to_f.positive? && r['h'].to_f.positive? }
end

raise ArgumentError, 'invalid redaction rects' unless sane_redaction_rects?(rects)

Try / catch

begin
  page.redact(rects)
rescue Pdfium::PdfiumError => e
  raise unless e.message == 'Failed to create redaction rect'
  page.redact(rects.select { |r| r['w'].to_f.positive? && r['h'].to_f.positive? })
end

Prevention

When it happens

Trigger: Redact input like {'x'=>0.5,'y'=>0.2,'w'=>0,'h'=>0.1} (zero-width highlight selections); tiny fractional w/h that round to zero; JSON payloads with missing w/h (nil.to_f becomes 0.0).

Common situations: UI annotation tools that permit zero-size selections; percentage-based coordinates that round down; unvalidated API payloads.

Related errors


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