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
- Disable the Complete action until files.attached? is true, and surface an inline 'attach at least one file' hint.
- If using direct-upload signed ids, verify the blobs exist and were attached (files.attached?) before enabling completion.
- 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
- Disable the Complete action until ActiveStorage reports files.attached?.
- With direct uploads, confirm signed blobs finished attaching before enabling completion.
- Verify signed ids belong to this commission, not another record.
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
- This commission has already been completed, so its files can
- This commission's deposit is no longer in a completable stat
- ${responseData.error}
- We could not find your uploaded files. Please upload them ag
- Sorry, shipping destinations have to be unique.
AI-assisted analysis of antiwork/gumroad@afeacbd394 (2026-08-21).
Data as JSON: /api/errors/a304e9a869b06d13.
Report an issue: GitHub.