antiwork/gumroad · error · DisputeEvidence::MergeCustomerCommunicationFilesService::MergeError

You can attach up to #{DisputeEvidence::MAX_CUSTOMER_COMMUNI

Error message

You can attach up to #{DisputeEvidence::MAX_CUSTOMER_COMMUNICATION_FILES} files.

What it means

DisputeEvidence::MergeCustomerCommunicationFilesService#perform raises MergeError when more than DisputeEvidence::MAX_CUSTOMER_COMMUNICATION_FILES (10) blobs are passed. Stripe accepts exactly one file for the customer_communication evidence field, so multiple uploads are merged into a single PDF; this cap bounds the merge input set.

Source

Thrown at app/services/dispute_evidence/merge_customer_communication_files_service.rb:45

  FILE_TOO_LARGE_MESSAGE = "One of the uploaded files exceeds the maximum size allowed."
  FILES_TOO_LARGE_MESSAGE = "The combined size of the uploaded files exceeds the maximum allowed, even after compression. Please remove a file or upload smaller versions."
  UNPROCESSABLE_FILE_MESSAGE = "One of the uploaded files could not be processed. Please check that every PDF opens correctly and is not password-protected."
  UNSUPPORTED_FILE_TYPE_MESSAGE = "One of the uploaded files is not a JPG, PNG, or PDF."

  def self.perform(blobs:, max_size:)
    new(blobs:, max_size:).perform
  end

  def initialize(blobs:, max_size:)
    @blobs = blobs
    @max_size = max_size
  end

  # Returns a new application/pdf ActiveStorage::Blob. The input blobs are left alone: the
  # caller purges them once the submission has actually been persisted.
  def perform
    if blobs.size > DisputeEvidence::MAX_CUSTOMER_COMMUNICATION_FILES
      raise MergeError, "You can attach up to #{DisputeEvidence::MAX_CUSTOMER_COMMUNICATION_FILES} files."
    end
    # The merged output is always application/pdf, so the model's content-type validation never
    # sees the inputs. Everything below hands seller-supplied bytes to ImageMagick and qpdf.
    unless blobs.all? { _1.content_type.in?(DisputeEvidence::ALLOWED_FILE_CONTENT_TYPES) }
      raise MergeError, UNSUPPORTED_FILE_TYPE_MESSAGE
    end
    raise FilesTooLargeError, FILE_TOO_LARGE_MESSAGE if blobs.any? { _1.byte_size > max_size }

    downloaded_files = download_blobs
    merged_path = merge_within_size_budget(downloaded_files)

    File.open(merged_path) do |file|
      ActiveStorage::Blob.create_and_upload!(io: file, filename: MERGED_FILENAME, content_type: "application/pdf")
    end
  ensure
    downloaded_files&.each { _1[:tempfile].close! }
    File.unlink(merged_path) if merged_path && File.exist?(merged_path)
  end

View on GitHub (pinned to afeacbd394)

Solutions

  1. Keep the total count (including any previously saved attachment) at or below 10
  2. Combine several screenshots into one taller image or one PDF before uploading
  3. Replace the existing attachment with a single consolidated file instead of adding more

Example fix

# before
# 9 previously attached + 3 new uploads = 12 blobs
MergeCustomerCommunicationFilesService.perform(blobs: twelve_blobs, max_size: budget)
# => MergeError: You can attach up to 10 files.

# after
# merge screenshots offline into 1 PDF, then attach 1 new upload (total 10)
MergeCustomerCommunicationFilesService.perform(blobs: ten_blobs, max_size: budget)
Defensive patterns

Strategy: validation

Validate before calling

if blobs.size > DisputeEvidence::MAX_CUSTOMER_COMMUNICATION_FILES
  raise "attach at most #{DisputeEvidence::MAX_CUSTOMER_COMMUNICATION_FILES} files"
end

Type guard

def within_customer_communication_file_limit?(blobs)
  blobs.size <= DisputeEvidence::MAX_CUSTOMER_COMMUNICATION_FILES
end

Try / catch

begin
  DisputeEvidence::MergeCustomerCommunicationFilesService.perform(blobs:, max_size: budget)
rescue DisputeEvidence::MergeCustomerCommunicationFilesService::MergeError => e
  flash.now[:alert] = e.message # controller already does exactly this
end

Prevention

When it happens

Trigger: Submitting the dispute evidence form with more than 10 files. Note the controller folds the already-attached customer_communication_file into the merge inputs, so 10 fresh uploads plus 1 previously saved attachment counts as 11 and fails.

Common situations: Sellers uploading a long chat history as many separate screenshots; returning to the dispute page across sessions and adding a few more files each time until the cumulative count crosses 10.

Related errors


AI-assisted analysis of antiwork/gumroad@afeacbd394 (2026-08-21). Data as JSON: /api/errors/c2321f9db9b47a9e. Report an issue: GitHub.