antiwork/gumroad · error · Link::LinkInvalid
Memberships should only have one Tier version category.
Error message
Memberships should only have one Tier version category.
What it means
Raised as Link::LinkInvalid by Link#valid_tier_version_structure when a membership product does not have exactly one alive variant_category. Memberships are modeled with a single 'Tier' variant category holding the tier variants; 0 or 2+ alive categories breaks that contract and the save is aborted. Skipped entirely for deleted or archived links, or when purchase_disabled_at just changed.
Source
Thrown at app/models/link.rb:1884
def alive_category_variants_presence
return if deleted_at.present?
return if archived?
has_alive_categories_without_variants = variant_categories.alive.left_joins(:alive_variants).where(base_variants: { id: nil }).exists?
if has_alive_categories_without_variants
errors.add(:base, "Sorry, the product versions must have at least one option.")
end
end
def valid_tier_version_structure
return if deleted_at.present?
return if archived?
return if purchase_disabled_at.present? && purchase_disabled_at_changed?
if variant_categories.alive.size != 1
errors.add(:base, "Memberships should only have one Tier version category.")
raise LinkInvalid, "Memberships should only have one Tier version category."
return
end
if variant_categories.alive.first.variants.alive.size == 0
errors.add(:base, "Memberships should have at least one tier.")
raise LinkInvalid, "Memberships should have at least one tier."
end
end
def quantity_enabled_state_is_allowed
if quantity_enabled && !can_enable_quantity?
errors.add(:base, "Customers cannot be allowed to choose a quantity for this product.")
end
end
def custom_permalink_or_is_licensed_changed?
custom_permalink_changed? || is_licensed_changed?
endView on GitHub (pinned to afeacbd394)
Solutions
- Ensure membership products have exactly one alive variant category named for tiers; soft-delete extras before saving.
- For API-created memberships, create the single Tier category then its variants — never multiple categories.
- Rescue Link::LinkInvalid and show errors.full_messages.
Example fix
# before: two alive categories on a membership link.variant_categories.alive.count # => 2 link.save! # LinkInvalid # after: keep exactly one Tier category link.variant_categories.alive.where.not(name: "Tier").each(&:mark_deleted) link.save!
Defensive patterns
Strategy: validation
Validate before calling
return { error: 'One Tier category required.' } if link.is_membership && link.variant_categories.alive.size != 1 Try / catch
begin
link.save!
rescue Link::LinkInvalid
render json: { errors: link.errors.full_messages }, status: :unprocessable_entity
end Prevention
- Only ever create a single variant category on memberships (the Tier).
- Audit imports/scripts that touch variant_categories on membership links.
- Deleted/archived links and purchase_disabled_at transitions skip the check — don't rely on that to hide bad data.
When it happens
Trigger: Saving an alive, non-archived membership link whose variant_categories.alive count is not 1 — creating a membership with no Tier category, or a duplicate Tier category (often via API/imports creating categories directly).
Common situations: Bulk importers or API clients creating variant categories the UI never would; cleanup scripts that soft-delete the one alive category; migrations leaving stray alive categories on membership links.
Related errors
- Memberships should have at least one tier.
- Sorry, shipping destinations have to be unique.
- The product needs to be shippable to at least one destinatio
- You have to confirm your email address before you can do tha
- This product was unpublished by Gumroad and cannot be republ
AI-assisted analysis of antiwork/gumroad@afeacbd394 (2026-08-21).
Data as JSON: /api/errors/9effbbe81cf58acd.
Report an issue: GitHub.