antiwork/gumroad · error · DisputeEvidence::MergeCustomerCommunicationFilesService::MergeError
One of the uploaded files could not be processed. Please che
Error message
One of the uploaded files could not be processed. Please check that every PDF opens correctly and is not password-protected.
What it means
merge() shells out via Open3.capture3('qpdf', '--empty', '--pages', *page_paths, '--', merged_path); an exit status outside QPDF_SUCCESS_EXIT_CODES logs qpdf's stderr and raises MergeError with UNPROCESSABLE_FILE_MESSAGE. Typical qpdf failures are password-protected/encrypted input PDFs and malformed or corrupt PDF structure — qpdf cannot copy pages it cannot decrypt or parse.
Source
Thrown at app/services/dispute_evidence/merge_customer_communication_files_service.rb:117
raise FilesTooLargeError, FILES_TOO_LARGE_MESSAGE
end
def merge(downloaded_files, compression)
page_paths = []
downloaded_files.each do |downloaded_file|
if downloaded_file[:content_type].in?(IMAGE_CONTENT_TYPES)
page_paths << image_to_pdf_page(downloaded_file[:tempfile].path, compression)
else
page_paths << downloaded_file[:tempfile].path
end
end
merged_path = "#{Dir.tmpdir}/dispute_evidence_merged_#{SecureRandom.hex}.pdf"
_stdout, stderr, status = Open3.capture3("qpdf", "--empty", "--pages", *page_paths, "--", merged_path)
unless QPDF_SUCCESS_EXIT_CODES.include?(status.exitstatus)
Rails.logger.error("[#{self.class.name}] qpdf failed: #{stderr}")
File.unlink(merged_path) if File.exist?(merged_path)
raise MergeError, UNPROCESSABLE_FILE_MESSAGE
end
merged_path
ensure
(page_paths - downloaded_files.map { _1[:tempfile].path }).each do |generated_path|
File.unlink(generated_path) if File.exist?(generated_path)
end
end
# Recompressing through JPEG also sidesteps the PNG variants (16-bit depth, interlaced)
# that both Stripe and Prawn reject — see
# Purchases::DisputeEvidenceController#covert_and_optimize_blob_if_needed.
def image_to_pdf_page(image_path, compression)
image = MiniMagick::Image.open(image_path)
image.auto_orient
image.resize("#{compression[:max_dimension]}x#{compression[:max_dimension]}>") if compression[:max_dimension]
image.format("jpg")
image.quality(compression[:quality]).colorspace("sRGB").stripView on GitHub (pinned to afeacbd394)
Solutions
- Open every submitted PDF locally and confirm it loads without a password prompt
- Re-export/print-to-PDF the encrypted document without a password, then re-upload
- Re-download or regenerate the corrupt file and submit again
- If you operate the app, check the logged '[...MergeCustomerCommunicationFilesService] qpdf failed:' stderr for the exact qpdf diagnostic
Example fix
# before blobs = [encrypted_statement_pdf, chat_jpg] # qpdf: 'file is encrypted' # => MergeError: One of the uploaded files could not be processed... # after # print-to-PDF the statement without encryption -> statement.pdf blobs = [statement_pdf, chat_jpg]
Defensive patterns
Strategy: try-catch
Validate before calling
# pre-flight each PDF the same way the merge does
Open3.capture3('qpdf', '--show-encryption', pdf_path).then do |_out, _err, status|
raise 'password-protected or unreadable PDF' unless status.success? # exit 0 = unencrypted, parseable
end Try / catch
begin
DisputeEvidence::MergeCustomerCommunicationFilesService.perform(blobs:, max_size: budget)
rescue DisputeEvidence::MergeCustomerCommunicationFilesService::MergeError => e
# e.message is already seller-safe; the real qpdf stderr is in the Rails log
Rails.logger.warn("merge rejected: #{e.message}")
redirect_back alert: e.message
end Prevention
- Open every PDF locally before upload; a password prompt means it will fail the merge
- Re-export encrypted statements via print-to-PDF to strip the password
- The exact qpdf diagnostic is logged as '[...MergeCustomerCommunicationFilesService] qpdf failed: <stderr>' — search the logs when triaging
When it happens
Trigger: One of the inputs is a password-protected bank statement or an owner-encrypted PDF; a PDF truncated during download; a zero-byte or fake .pdf (e.g. an HTML error page renamed to .pdf).
Common situations: Financial documents that ship with owner passwords; files corrupted in transit; exports from buggy third-party tools that produce non-conforming PDFs.
Related errors
- The combined size of the uploaded files exceeds the maximum
- You can attach up to #{DisputeEvidence::MAX_CUSTOMER_COMMUNI
- One of the uploaded files is not a JPG, PNG, or PDF.
- One of the uploaded files exceeds the maximum size allowed.
- Message is required
AI-assisted analysis of antiwork/gumroad@afeacbd394 (2026-08-21).
Data as JSON: /api/errors/823d55b860420f15.
Report an issue: GitHub.