antiwork/gumroad · error · ResponseError
${responseData.error}
Error message
${responseData.error} What it means
createUpsell (app/javascript/data/upsells.ts:25-67) POSTs the upsell payload and parses the body unconditionally with typia.assert; when it decodes to success:false it throws ResponseError(responseData.error) carrying the server's own message. This is the checkout dashboard's application-level validation failure path: Rails rejected the upsell (invalid name/text, product_ids containing products that cannot be offered, bad offer_code, upsell_variants referencing variants that don't belong to the products) and explained why in error.
Source
Thrown at app/javascript/data/upsells.ts:64
description,
cross_sell: isCrossSell,
replace_selected_products: replaceSelectedProducts,
universal,
product_id: productId,
variant_id: variantId ?? undefined,
offer_code: offerCode ?? undefined,
product_ids: productIds,
upsell_variants: upsellVariants.map(({ selectedVariantId, offeredVariantId }) => ({
selected_variant_id: selectedVariantId,
offered_variant_id: offeredVariantId,
})),
paused,
},
});
const responseData = typia.assert<
{ success: true; upsells: Upsell[]; pagination: PaginationProps } | { success: false; error: string }
>(await response.json());
if (!responseData.success) throw new ResponseError(responseData.error);
return responseData;
};
export const updateUpsell = async (
id: string,
{
name,
text,
description,
isCrossSell,
replaceSelectedProducts,
universal,
productId,
variantId,
offerCode,
productIds,
upsellVariants,View on GitHub (pinned to afeacbd394)
Solutions
- Read e.message — the server's error string names the exact invalid field or rule
- Fix the named field (name/text required, valid product/variant ids, in-range offer code) and resubmit
- Re-pick the offer products from a fresh picker load so product_ids are current
- Validate required fields client-side before POSTing to avoid the round trip
- If the error is stale-state (product gone), reload the upsells page and rebuild the selection
Example fix
// client-side gate mirroring server rules before createUpsell
const payloadValid =
name.trim() !== "" && text.trim() !== "" && productId !== "" &&
productIds.every((id) => availableProductIds.has(id));
if (!payloadValid) return showError("Fill in name, text, and valid products first.");
await createUpsell(payload); Defensive patterns
Strategy: validation
Validate before calling
const validUpsellPayload = (p: UpsellPayload) =>
p.name.trim() !== "" && p.text.trim() !== "" && p.productId !== "" &&
p.productIds.every((id) => availableProductIds.has(id));
if (!validUpsellPayload(payload)) return showError("Fill in name, text, and valid products."); Type guard
import typia from "typia";
const isUpsellEnvelope = typia.is<
{ success: true; upsells: Upsell[]; pagination: PaginationProps } | { success: false; error: string }
>; Try / catch
try {
setState(await createUpsell(payload));
} catch (e) {
assertResponseError(e);
showError(e.message); // names the exact server-side rule that failed
} Prevention
- Require name/text and re-validate product ids against a freshly loaded picker before POSTing
- Range-check offer_code amounts client-side
- Show e.message verbatim — the server already explains the refusal
When it happens
Trigger: Saving a new upsell in CheckoutDashboard/UpsellsPage.tsx with a blank name or text; selecting offer products that are unpublished, deleted, or belong to another seller; an offer_code amount out of range; upsell_variants pairing variant ids from different products; universal upsell rules violated server-side.
Common situations: Product picker state holding ids for products deleted/unpublished after the picker loaded; percentage/cent amounts typed beyond limits; variant dropdowns stale after the product's variants were edited; concurrent editors changing the same catalog.
Related errors
- Something went wrong.
- Something went wrong.
- Something went wrong.
- ${responseData.error}
- Something went wrong.
AI-assisted analysis of antiwork/gumroad@afeacbd394 (2026-08-21).
Data as JSON: /api/errors/b6cd7c16000b3ac0.
Report an issue: GitHub.