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

One of the uploaded files exceeds the maximum size allowed.

Error message

One of the uploaded files exceeds the maximum size allowed.

What it means

perform raises FilesTooLargeError (a subclass of MergeError) when any single blob's byte_size exceeds max_size. max_size is dispute_evidence.customer_communication_file_max_size — the remaining Stripe combined-size budget (STRIPE_MAX_COMBINED_FILE_SIZE minus what other evidence fields already consume) — so the effective per-file ceiling can be smaller than a fixed limit and shrinks as other evidence is attached.

Source

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

  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

  private
    attr_reader :blobs, :max_size

    def download_blobs
      downloaded_files = []
      blobs.each do |blob|

View on GitHub (pinned to afeacbd394)

Solutions

  1. Compress the offending file below the remaining budget (re-export the PDF with lower image quality, scan at 150–200 DPI, save photos as ~80% JPEG)
  2. Check the sizes of all files being submitted this round, including the previously attached one
  3. If other evidence fields are consuming the budget, trim those files too

Example fix

# before
blobs = [pdf_blob] # 6 MB, remaining budget 5 MB
# => FilesTooLargeError: One of the uploaded files exceeds the maximum size allowed.

# after
# re-export with compressed images -> 2.5 MB PDF
blobs = [smaller_pdf_blob]
Defensive patterns

Strategy: validation

Validate before calling

max_size = dispute_evidence.customer_communication_file_max_size # remaining Stripe budget
raise 'file too large' if blobs.any? { _1.byte_size > max_size }

Type guard

def all_files_within?(blobs, max_size)
  blobs.none? { _1.byte_size > max_size }
end

Try / catch

begin
  DisputeEvidence::MergeCustomerCommunicationFilesService.perform(blobs:, max_size: budget)
rescue DisputeEvidence::MergeCustomerCommunicationFilesService::FilesTooLargeError => e
  redirect_back alert: e.message # per-file and combined overages share this error class
end

Prevention

When it happens

Trigger: One upload bigger than the currently remaining Stripe budget; a multi-MB scan submitted after other large evidence files have already claimed most of the budget.

Common situations: High-DPI scans of receipts/contracts, 'print-quality' PDF exports, phone photos at full resolution.

Related errors


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