antiwork/gumroad · error · Link::LinkInvalid
Memberships should have at least one tier.
Error message
Memberships should have at least one tier.
What it means
Raised as Link::LinkInvalid by Link#valid_tier_version_structure when a membership's single alive variant category contains zero alive variants. The membership must sell at least one tier, so an empty Tier category aborts the save. Same skip conditions as its sibling check: deleted, archived, or purchase_disabled_at-changed links are exempt.
Source
Thrown at app/models/link.rb:1890
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?
end
def description_scrubber
unless Loofah::HTML5::SafeList::ACCEPTABLE_CSS_PROPERTIES.include?("position")
# TODO (vishal): iframe.ly adds "position" style, which is not allowed by default.
# We should be able to remove this once https://github.com/flavorjones/loofah/pull/258 is merged.
Loofah::HTML5::SafeList::ACCEPTABLE_CSS_PROPERTIES.add("position")View on GitHub (pinned to afeacbd394)
Solutions
- Keep at least one alive tier variant on the Tier category — block removal of the last row in the UI.
- For imports, create category and at least one variant in the same transaction.
- Rescue Link::LinkInvalid and show errors.full_messages.
Example fix
# before
link.save! # LinkInvalid: zero alive tiers
# after
if link.variant_categories.alive.first.variants.alive.empty?
return { error: "Memberships should have at least one tier." }
end
link.save! Defensive patterns
Strategy: validation
Validate before calling
return { error: 'At least one tier required.' } if link.is_membership && link.variant_categories.alive.first&.variants&.alive&.empty? Try / catch
begin
link.save!
rescue Link::LinkInvalid
render json: { errors: link.errors.full_messages }, status: :unprocessable_entity
end Prevention
- Prevent deleting the last alive tier variant in the tier editor.
- Create category + at least one variant atomically during imports.
- Check variants.alive, not all variants — soft-deleted tiers don't count.
When it happens
Trigger: Saving an alive membership link where variant_categories.alive.first.variants.alive is empty — seller deleted every tier row before saving, or an import created the category but no variants, or all variants were soft-deleted.
Common situations: Tier editor grid allowing the last row to be removed; imports partial-failing after category creation; cleanup jobs soft-deleting variants without checking membership integrity.
Related errors
- Memberships should only have one Tier version category.
- 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/44052408a9c2c1f8.
Report an issue: GitHub.