antiwork/gumroad · error · ResponseError
Something went wrong.
Error message
Something went wrong.
What it means
ResponseError ("Something went wrong.") thrown by getMissedPosts when GET /customers/missed_posts/:purchase_id?purchase_email=... answers non-2xx. This feeds the buyer Library's "missed posts" list, and the purchase_email parameter doubles as the access check. Since request() pre-handles 5xx/429/network errors, this throw means a 4xx — typically 404 when the purchase does not exist or the email does not match it, or 401 for session problems.
Source
Thrown at app/javascript/data/customers.ts:212
response,
cancel: () => abort.abort(),
};
};
export type MissedPost = {
id: string;
name: string;
url: string;
published_at: string;
};
export const getMissedPosts = (purchaseId: string, purchaseEmail: string) =>
request({
method: "GET",
accept: "json",
url: Routes.missed_posts_path(purchaseId, { purchase_email: purchaseEmail }),
})
.then((res) => {
if (!res.ok) throw new ResponseError();
return res.json();
})
.then((json) => typia.assert<MissedPost[]>(json));
export type CustomerEmail = { id: string; name: string; state: string; state_at: string } & (
| { type: "receipt"; url: string }
| { type: "post" }
);
export const getCustomerEmails = (purchaseId: string) =>
request({
method: "GET",
accept: "json",
url: Routes.customer_emails_path(purchaseId),
})
.then((res) => {
if (!res.ok) throw new ResponseError();
return res.json();
})View on GitHub (pinned to afeacbd394)
Solutions
- Confirm the purchase_email passed in matches the purchase's email exactly, including spelling — it is the access credential for this endpoint.
- DevTools → Network: a 404 means purchase-not-found-or-email-mismatch; verify the purchase exists under that email in the library.
- 401: re-authenticate (reload to login) and retry.
- Handle the failure by hiding the missed-posts section rather than breaking the whole library page.
Defensive patterns
Strategy: try-catch
Validate before calling
const EMAIL = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!purchaseId || !EMAIL.test(purchaseEmail))
throw new Error("A purchase and its email are required to list missed posts.");
await getMissedPosts(purchaseId, purchaseEmail); Type guard
import { ResponseError } from "$app/utils/request";
const isResponseError = (e: unknown): e is ResponseError => e instanceof ResponseError; Try / catch
import { assertResponseError } from "$app/utils/request";
try {
const posts = await getMissedPosts(purchaseId, purchaseEmail);
} catch (e) {
assertResponseError(e);
setMissedPosts([]); // hide the section instead of failing the library page
} Prevention
- The purchase_email is the access credential — always pass the exact email tied to the purchase.
- Bind purchaseId/purchaseEmail from the purchase's own record, never from URL parameters a user can edit.
- Degrade to an empty missed-posts section; a single bad purchase should not break the Library.
When it happens
Trigger: Passing a purchase_email that differs from the purchase's actual email (typo, different casing/alias, or the purchase was made with another address); a purchase_id for a deleted or fully refunded purchase; reader session expired on the library page; ids hand-copied from an old link.
Common situations: Buyers forwarding library links between their own two email addresses; purchases made via PayPal with a different email than the Gumroad login; test purchases later deleted; library tabs left open across account switches.
Related errors
- Something went wrong.
- Something went wrong.
- Something went wrong.
- Something went wrong.
- Something went wrong.
AI-assisted analysis of antiwork/gumroad@afeacbd394 (2026-08-21).
Data as JSON: /api/errors/43db61b5ad6fe954.
Report an issue: GitHub.