antiwork/gumroad · error · Purchase::PurchaseInvalid
giftee_purchase.errors.full_messages[0]
Error message
giftee_purchase.errors.full_messages[0]
What it means
Gift checkouts build a second, recipient-side purchase (perceived_price_cents forced to 0, is_gift_receiver_purchase true) and run process! on it. If that giftee purchase ends up with validation errors, the first full message is re-raised as PurchaseInvalid - so the message text is whatever the underlying model validation produced, not a fixed string. This is a passthrough of giftee_purchase.errors.full_messages[0].
Source
Thrown at app/services/purchase/create_service.rb:508
next if custom_field.type == CustomField::TYPE_TEXT && !custom_field.required? && values[custom_field.external_id].blank?
purchase.purchase_custom_fields << PurchaseCustomField.build_from_custom_field(custom_field:, value: values[custom_field.external_id], bundle_product:)
end
end
def create_giftee_purchase
giftee_purchase_params = purchase_params.except(:discount_code, :paypal_order_id).merge(
email: giftee_email,
is_multi_buy: false,
is_preorder_authorization: false,
perceived_price_cents: 0,
is_gift_sender_purchase: false,
is_gift_receiver_purchase: true
)
giftee_purchase = build_purchase(giftee_purchase_params)
giftee_purchase.purchaser = giftee_purchaser
giftee_purchase.gift_received = gift
giftee_purchase.process!
raise Purchase::PurchaseInvalid, giftee_purchase.errors.full_messages[0] if giftee_purchase.errors.present?
end
def giftee_purchaser
@_giftee_purchaser ||= gift_params[:giftee_id].present? ? User.alive.find_by_external_id(gift_params[:giftee_id]) : User.alive.by_email(gift_params[:giftee_email]).last
end
def giftee_email
giftee_purchaser&.email || gift_params[:giftee_email]
end
def build_preorder(locked_rate: nil)
raise Purchase::PurchaseInvalid, "The product was just released. Refresh the page to purchase it." unless product.is_in_preorder_state?
self.preorder = product.preorder_link.build_preorder(purchase)
if purchase.is_part_of_combined_charge?
purchase.prepare_for_charge!(locked_rate:)
else
preorder.authorize!(locked_rate:)View on GitHub (pinned to afeacbd394)
Solutions
- Inspect giftee_purchase.errors (all messages, not just the first) in a console or debugger to identify the failing validation.
- Fix the offending field - most commonly the giftee email - and resubmit.
- Integrators: log the full errors object server-side when this passthrough fires, since the raised message alone may hide additional errors.
Example fix
# before: only the first error surfaces
raise Purchase::PurchaseInvalid, giftee_purchase.errors.full_messages[0] if giftee_purchase.errors.present?
# after (debugging aid): log everything, then raise the first
Rails.logger.warn("giftee purchase invalid: #{giftee_purchase.errors.full_messages.join(', ')}")
raise Purchase::PurchaseInvalid, giftee_purchase.errors.full_messages[0] if giftee_purchase.errors.present? Defensive patterns
Strategy: try-catch
Validate before calling
giftee = gift_params[:giftee_id].present? ? User.alive.find_by_external_id(gift_params[:giftee_id]) : User.alive.by_email(gift_params[:giftee_email]).last raise ArgumentError, 'giftee user not found' if gift_params[:giftee_id].present? && giftee.nil?
Try / catch
begin
purchase, error = Purchase::CreateService.new(product:, params:, buyer:).perform
rescue Purchase::PurchaseInvalid => e
# passthrough of giftee_purchase model errors - log context, surface the message
Rails.logger.warn("giftee purchase invalid: #{e.message}")
render_checkout_error(e.message)
end Prevention
- Validate the giftee email/user exists and is alive before submitting the gift.
- Log surrounding context (giftee email, purchaser email) when this fires - the raised message is only the first of possibly several errors.
- Reproduce with the same giftee params in a console to see the full errors array.
When it happens
Trigger: Gift flow completes create_gift, giftee_purchase.process! runs, and giftee_purchase.errors is non-empty afterwards - e.g. recipient-side email or purchase-model validations failing on the zero-priced receiver purchase.
Common situations: Giftee email that fails user/purchase validations; giftee account state issues (deleted/alive checks in giftee_purchaser lookup); any recipient-side model validation tripping during process!.
Related errors
- You can't gift your own product. To give it away for free, c
- You cannot gift a product to yourself. Please try gifting to
- Gift purchases cannot be on installment plans.
- The creator has disabled gifting for their products.
- Gifting is not yet enabled for pre-orders.
AI-assisted analysis of antiwork/gumroad@afeacbd394 (2026-08-21).
Data as JSON: /api/errors/a1b6ea154b63616f.
Report an issue: GitHub.