{"record":{"id":"e97b01f942f140da","repo":"antiwork/gumroad","slug":"sorry-this-offer-is-no-longer-available","errorCode":null,"errorMessage":"Sorry, this offer is no longer available.","messagePattern":"Sorry, this offer is no longer available\\.","errorType":"exception","errorClass":"Purchase::PurchaseInvalid","httpStatus":null,"severity":"error","filePath":"app/services/purchase/create_service.rb","lineNumber":113,"sourceCode":"        end\n      end\n\n      if purchase.offer_code&.minimum_amount_cents.present?\n        valid_items = params[:cart_items]\n        valid_items = if purchase.offer_code.universal\n          excluded_permalinks = purchase.offer_code.excluded_products.pluck(:unique_permalink)\n          valid_items.reject { excluded_permalinks.include?(_1[:permalink]) }\n        else\n          valid_items.filter { purchase.offer_code.products.find_by(unique_permalink: _1[:permalink]).present? }\n        end\n        if valid_items.map { _1[:price_cents].to_i }.sum < purchase.offer_code.minimum_amount_cents\n          raise Purchase::PurchaseInvalid, \"Sorry, you have not met the offer code's minimum amount.\"\n        end\n      end\n\n      if params[:accepted_offer].present?\n        upsell = Upsell.available_to_customers.find_by_external_id(params[:accepted_offer][:id])\n        raise Purchase::PurchaseInvalid, \"Sorry, this offer is no longer available.\" unless upsell.present?\n        if upsell.cross_sell?\n          if upsell.not_replace_selected_products?\n            cart_product_permalinks = params[:cart_items].reject { _1[:permalink] == product.unique_permalink }.map { _1[:permalink] }\n            if upsell.not_is_content_upsell? && (upsell.universal ? product.user.products : upsell.selected_products).where(unique_permalink: cart_product_permalinks).empty?\n              raise Purchase::PurchaseInvalid, \"The cart does not have any products to which the upsell applies.\"\n            end\n          end\n\n          # The original discount is retained if it is better than the upsell\n          # discount. The client can't automatically set the upsell discount\n          # because it doesn't have a \"code\". Thus, upsell discount should only\n          # be applied when the purchase does not already have a discount code.\n          if purchase.offer_code.blank? && upsell.offer_code&.evaluate_for_buyer(buyer, product: purchase.link).present? &&\n             (!params[:is_purchasing_power_parity_discounted] || perceived_price_matches_accepted_offer?(upsell.offer_code))\n            purchase.offer_code = upsell.offer_code\n          end\n        end\n        purchase.build_upsell_purchase(","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/antiwork/gumroad/blob/afeacbd394069a1cbf0c6c50ee8e900925050370/app/services/purchase/create_service.rb#L95-L131","documentation":"When params[:accepted_offer] is present, Purchase::CreateService looks the upsell up in Upsell.available_to_customers.find_by_external_id(params[:accepted_offer][:id]). If no available upsell matches (not found, no longer available_to_customers, expired, or deleted by the seller), Purchase::PurchaseInvalid is raised and the purchase does not proceed with the offer.","triggerScenarios":"Accepting an upsell that expired or was deleted between when the checkout page rendered and when the buyer clicked accept; a stale checkout tab; a wrong or tampered accepted_offer id in the request.","commonSituations":"Time-limited upsell offers; sellers editing/deleting upsells while carts are open; long-lived checkout pages on mobile.","solutions":["Refresh the checkout page — if the offer is still live it will be re-offered with a valid reference","Otherwise complete the purchase without the upsell; the base purchase is unaffected","If building a client, treat accepted_offer as optional and re-validate availability before submitting"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"if params[:accepted_offer].present?\n  upsell = Upsell.available_to_customers.find_by_external_id(params[:accepted_offer][:id])\n  raise 'offer no longer available' if upsell.nil?\nend","typeGuard":"def accepted_offer_still_available?(offer_id)\n  Upsell.available_to_customers.exists?(external_id: offer_id)\nend","tryCatchPattern":"begin\n  Purchase::CreateService.new(user: buyer, params: purchase_params).perform\nrescue Purchase::PurchaseInvalid => e\n  if e.message.include?('no longer available')\n    purchase_params.delete(:accepted_offer) # complete the base purchase without the upsell\n    retry\n  else\n    raise\n  end\nend","preventionTips":["Treat accepted_offer as advisory: re-check Upsell.available_to_customers right before submit","Expect offers to expire between render and accept — always keep a purchase-without-offer path","Short-lived checkout sessions for products with time-limited upsells reduce the window for this race"],"tags":["ruby","rails","upsell","checkout","stale-reference"],"backgroundTag":"expired-offer-reference","analyzedSha":"afeacbd394069a1cbf0c6c50ee8e900925050370","analyzedAt":"2026-08-21T17:58:52.159Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}