antiwork/gumroad · error · ActiveRecord::RecordInvalid

Attach at least one file before completing this commission.

Error message

Attach at least one file before completing this commission.

What it means

Raised as ActiveRecord::RecordInvalid by Commission#ensure_deliverable_is_attached! (app/models/commission.rb:152) when completing a commission with no ActiveStorage attachments under files. It is a precondition guard on the completion flow: the completion charge bills the buyer for deliverables, so at least one file must exist before the charge is attempted. The commission's errors get the :base message 'Attach at least one file before completing this commission.'.

Source

Thrown at app/models/commission.rb:156

      minimum = deposit_purchase.link.currency["min_price"]
      total = minimum if total.positive? && total < minimum
      total
    end

    # Refunding the deposit is how the Help Center tells sellers to reject a commission, and
    # nothing transitions the commission when they do — so the deposit is re-read at charge time.
    def ensure_deposit_is_chargeable!
      return if deposit_is_chargeable?

      errors.add(:base, "This commission's deposit is no longer in a completable state, so it can no longer be completed.")
      raise ActiveRecord::RecordInvalid, self
    end

    def ensure_deliverable_is_attached!
      return if files.attached?

      errors.add(:base, "Attach at least one file before completing this commission.")
      raise ActiveRecord::RecordInvalid, self
    end

    def deposit_is_chargeable?
      return false unless is_in_progress?

      # A fresh read, not the memoized association — a refund can land through another instance
      # after this commission was loaded. `find` rather than `reload` because the completion
      # purchase prices variants from the memoized deposit's loaded association objects.
      deposit = Purchase.find(deposit_purchase_id)
      # Including test: a seller buying their own commission product gets a `test_successful`
      # deposit, and completing it is a supported flow that skips charging entirely.
      return false unless Purchase::ALL_SUCCESS_STATES_INCLUDING_TEST.include?(deposit.purchase_state)

      !deposit.refunded? &&
        !deposit.stripe_partially_refunded? &&
        !deposit.chargedback_not_reversed?
    end

View on GitHub (pinned to afeacbd394)

Solutions

  1. Disable the Complete action until files.attached? is true, and surface an inline 'attach at least one file' hint.
  2. If using direct-upload signed ids, verify the blobs exist and were attached (files.attached?) before enabling completion.
  3. Rescue ActiveRecord::RecordInvalid on the completion call and show commission.errors.full_messages to the seller.

Example fix

# before
commission.complete! # RecordInvalid: no files attached

# after
unless commission.files.attached?
  return { error: "Attach at least one file before completing this commission." }
end
commission.complete!
Defensive patterns

Strategy: validation

Validate before calling

return { error: "Attach at least one file before completing." } unless commission.files.attached?

Try / catch

begin
  commission.complete!
rescue ActiveRecord::RecordInvalid
  render json: { errors: commission.errors.full_messages }, status: :unprocessable_entity
end

Prevention

When it happens

Trigger: Invoking commission completion (the complete endpoint / complete! path that calls ensure_deliverable_is_attached!) while commission.files.attached? is false — e.g. the seller never uploaded deliverables, or attachments were removed/purged before completing.

Common situations: Seller clicks Complete from a stale page before the upload finished signing/attaching; front-end lets the complete action fire with an empty file list; files were attached to a different record (wrong signed ids) so this record still has none.

Related errors


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