{"record":{"id":"09310865b75d035f","repo":"docusealco/docuseal","slug":"failed-to-create-redaction-rect","errorCode":null,"errorMessage":"Failed to create redaction rect","messagePattern":"Failed to create redaction rect","errorType":"exception","errorClass":"Pdfium::PdfiumError","httpStatus":null,"severity":"error","filePath":"lib/pdfium.rb","lineNumber":1407,"sourceCode":"      @text_objects = nil\n      @line_nodes = nil\n      @annotations = nil\n      @objects = nil\n    end\n\n    def remove_page_object(object_ptr)\n      raise PdfiumError, 'Failed to remove page object' if Pdfium.FPDFPage_RemoveObject(@page_ptr, object_ptr).zero?\n\n      Pdfium.FPDFPageObj_Destroy(object_ptr)\n    end\n\n    def draw_redaction_rects(rect_bounds)\n      rect_bounds.each do |left, bottom, right, top, color|\n        next if color == 'white'\n\n        rect_object = Pdfium.FPDFPageObj_CreateNewRect(left, bottom, right - left, top - bottom)\n\n        raise PdfiumError, 'Failed to create redaction rect' if rect_object.null?\n\n        Pdfium.FPDFPageObj_SetFillColor(rect_object, 0, 0, 0, 255)\n        Pdfium.FPDFPath_SetDrawMode(rect_object, 1, 0)\n        Pdfium.FPDFPage_InsertObject(@page_ptr, rect_object)\n      end\n    end\n\n    def redact_image_objects(rect_bounds)\n      bounds_ptrs = Array.new(4) { FFI::MemoryPointer.new(:float) }\n      matrix_ptr = FFI::MemoryPointer.new(:float, 6)\n\n      Pdfium.FPDFPage_CountObjects(@page_ptr).times do |index|\n        object_ptr = Pdfium.FPDFPage_GetObject(@page_ptr, index)\n\n        next if object_ptr.null?\n        next unless Pdfium.FPDFPageObj_GetType(object_ptr) == FPDF_PAGEOBJ_IMAGE\n        next if Pdfium.FPDFPageObj_GetBounds(object_ptr, *bounds_ptrs).zero?\n","sourceCodeStart":1389,"sourceCodeEnd":1425,"githubUrl":"https://github.com/docusealco/docuseal/blob/004a22c1c88109c7ba0b567df011a8cb13894001/lib/pdfium.rb#L1389-L1425","documentation":"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.","triggerScenarios":"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).","commonSituations":"UI annotation tools that permit zero-size selections; percentage-based coordinates that round down; unvalidated API payloads.","solutions":["Validate redaction input: require rect['w'].to_f > 0 and rect['h'].to_f > 0 before calling redact","Filter degenerate rects out of the batch instead of failing the whole page","Reject non-numeric or missing w/h at the API boundary rather than coercing nil to 0"],"exampleFix":"# before\npage.redact(all_rects)\n\n# after\npage.redact(all_rects.select { |r| r['w'].to_f.positive? && r['h'].to_f.positive? })","handlingStrategy":"validation","validationCode":"def sane_redaction_rects?(rects)\n  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? }\nend\n\nraise ArgumentError, 'invalid redaction rects' unless sane_redaction_rects?(rects)","typeGuard":null,"tryCatchPattern":"begin\n  page.redact(rects)\nrescue Pdfium::PdfiumError => e\n  raise unless e.message == 'Failed to create redaction rect'\n  page.redact(rects.select { |r| r['w'].to_f.positive? && r['h'].to_f.positive? })\nend","preventionTips":["Reject zero-area selections in the annotation UI before submission","Validate numeric w/h presence at the API boundary instead of relying on nil.to_f coercion","Unit-test redaction input with degenerate rects (w:0, h:0, negative values)"],"tags":["pdfium","redaction","geometry","input-validation","ruby"],"backgroundTag":"invalid-geometry","analyzedSha":"004a22c1c88109c7ba0b567df011a8cb13894001","analyzedAt":"2026-08-21T13:38:23.343Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}