antiwork/gumroad · error · Link::LinkInvalid

Please provide a price for the default payment option.

Error message

Please provide a price for the default payment option.

What it means

After the PWYW checks, every tier must carry an enabled price entry for the product's default recurrence (product.subscription_duration): the recurrence key must exist in recurrence_price_values and have enabled: true, otherwise Link::LinkInvalid. Tiered memberships bill on the product's default period, so every tier needs a price for it.

Source

Thrown at app/services/product/variant_category_updater_service.rb:602

            raise Link::LinkInvalid, "Please provide suggested payment options."
          end

          # error if "pay what you want" enabled but suggested price is too low
          variant[:recurrence_price_values].each do |recurrence, price_info|
            if price_info[:suggested_price_cents].present? && (price_info[:price_cents].to_i > price_info[:suggested_price_cents].to_i)
              errors.add(:base, "The suggested price you entered was too low.")
              raise Link::LinkInvalid, "The suggested price you entered was too low."
            end
          end
        end

        # error if missing pricing info for the product's default recurrence
        if product.subscription_duration.present? && (
          !variant[:recurrence_price_values][product.subscription_duration.to_s].present? ||
          !variant[:recurrence_price_values][product.subscription_duration.to_s][:enabled]
        )
          errors.add(:base, "Please provide a price for the default payment option.")
          raise Link::LinkInvalid, "Please provide a price for the default payment option."
        end
      end

      # error if variants have different recurrence options:
      # 1. Extract variant recurrence selections:
      # Ex. [["monthly", "yearly"], ["monthly"]]
      enabled_recurrences_for_variants = variants.map do |variant|
        variant[:recurrence_price_values].select { |k, v| v[:enabled] }.keys.sort
      end
      # 2. Ensure that they match
      # Ex. ["monthly", "yearly"] != ["monthly"] raises error
      enabled_recurrences_for_variants.each_with_index do |recurrences, index|
        next_recurrences = enabled_recurrences_for_variants[index + 1]
        if next_recurrences && recurrences != next_recurrences
          errors.add(:base, "All tiers must have the same set of payment options.")
          raise Link::LinkInvalid, "All tiers must have the same set of payment options."
        end
      end

View on GitHub (pinned to afeacbd394)

Solutions

  1. Enable and price the product's default payment option on every tier (e.g. monthly when subscription_duration is monthly)
  2. Or change the product's default recurrence to the period all tiers actually offer
  3. Verify no tier has the default period toggled off in the editor's pricing grid

Example fix

# before
# product.subscription_duration = 'monthly'
recurrence_price_values = { 'yearly' => { enabled: true, price_cents: 10_000 } }
# => Link::LinkInvalid: Please provide a price for the default payment option.

# after
recurrence_price_values = {
  'monthly' => { enabled: true, price_cents: 1000 },
  'yearly' => { enabled: true, price_cents: 10_000 }
}
Defensive patterns

Strategy: validation

Validate before calling

default = product.subscription_duration.to_s
variants.each do |v|
  entry = v[:recurrence_price_values][default]
  raise %(no price for default recurrence #{default}) if entry.blank? || !entry[:enabled]
end

Type guard

def tier_priced_for_default_recurrence?(variant_params, default_duration)
  entry = variant_params[:recurrence_price_values][default_duration.to_s]
  entry.present? && entry[:enabled]
end

Try / catch

begin
  VariantCategoryUpdaterService.new(product:, category_params:).process
rescue Link::LinkInvalid
  render_edit_form_with(product.errors.full_messages)
end

Prevention

When it happens

Trigger: Product default duration is 'monthly' but a tier only enables the 'yearly' option, or the monthly entry exists with enabled: false — the presence/enabled check fails and the save aborts.

Common situations: Switching a product's default billing period after tiers were configured; selectively disabling one period on one tier.

Understand the failure class

Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.

Related errors


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