antiwork/gumroad · error · Purchase::PurchaseInvalid

You cannot gift a product to yourself. Please try gifting to

Error message

You cannot gift a product to yourself. Please try gifting to another email.

What it means

Raised when the gift recipient email equals the purchaser email (giftee_email == purchase_params[:email]). Gumroad's gift flow creates a second, recipient-side purchase, so gifting to yourself is rejected; giftee_email resolves from gift_params[:giftee_id]'s user or gift_params[:giftee_email].

Source

Thrown at app/services/purchase/create_service.rb:330

        end

        purchase = result[:purchase] || restartable_subscription.original_purchase
        self.purchase = purchase
        Rails.logger.info("Subscription #{restartable_subscription.external_id} restarted during checkout for product #{product.id}")
        return purchase, nil
      else
        return nil, result[:error_message]
      end
    end

    def create_gift
      # A seller buying their own product can only ever be a test purchase, and test purchases were
      # never built for gifts, so this case has to be rejected. The message names what the seller
      # actually did and points at the supported way to give a product away, because the old wording
      # ("Test gift purchases have not been enabled yet.") described an internal capability and read
      # as a flag we could switch on for them, which generated support tickets asking us to do that.
      raise Purchase::PurchaseInvalid, "You can't gift your own product. To give it away for free, create a 100% off discount code under Checkout > Discounts and share the checkout link." if buyer == product.user
      raise Purchase::PurchaseInvalid, "You cannot gift a product to yourself. Please try gifting to another email." if giftee_email == purchase_params[:email]
      raise Purchase::PurchaseInvalid, "Gift purchases cannot be on installment plans." if params[:pay_in_installments]

      if product.can_gift?
        gift = product.gifts.build(giftee_email:, gift_note: gift_params[:gift_note], gifter_email: params[:purchase][:email], is_recipient_hidden: gift_params[:giftee_email].blank?)
        error_message = gift.save ? nil : gift.errors.full_messages[0]
        raise Purchase::PurchaseInvalid, error_message if error_message.present?

        gift
      else
        error_message = product.user.gifting_disabled? ? "The creator has disabled gifting for their products." : "Gifting is not yet enabled for pre-orders."
        raise Purchase::PurchaseInvalid, error_message
      end
    end

    def validate_perceived_price
      if purchase_params[:perceived_price_cents] && !Purchase::MAX_PRICE_RANGE.cover?(purchase_params[:perceived_price_cents])
        raise Purchase::PurchaseInvalid, "Purchase price is invalid. Please check the price."
      end

View on GitHub (pinned to afeacbd394)

Solutions

  1. Enter a different recipient email address.
  2. If the buyer wants the product on their own account, complete a normal non-gift purchase.
  3. Integrators: compare the two emails client-side and disable submit while they match.

Example fix

# before: recipient field autofilled with the buyer's own address
gift_params[:giftee_email] = purchase_params[:email]

# after: block submission until the recipient differs
gift_params[:giftee_email] = nil if gift_params[:giftee_email] == purchase_params[:email]
Defensive patterns

Strategy: validation

Validate before calling

recipient = gift_params[:giftee_id].present? ? User.alive.find_by_external_id(gift_params[:giftee_id])&.email : gift_params[:giftee_email]
params.delete(:gift) if recipient == purchase_params[:email]

Type guard

def gift_to_self?(giftee_email, purchaser_email)
  giftee_email.to_s.downcase == purchaser_email.to_s.downcase
end

Try / catch

begin
  Purchase::CreateService.new(product:, params:, buyer:).perform
rescue Purchase::PurchaseInvalid => e
  render_checkout_error(e.message) if e.message.start_with?('You cannot gift a product to yourself')
end

Prevention

When it happens

Trigger: params[:gift][:giftee_email] (or the email of the user resolved by giftee_id) exactly equals params[:purchase][:email] on a gift checkout.

Common situations: Buyer types their own address into the recipient field by accident; browser autofill populating both email fields identically.

Related errors


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