antiwork/gumroad · error · ResponseError

Something went wrong.

Error message

Something went wrong.

What it means

ResponseError ("Something went wrong.") is thrown by Gumroad's data layer when an endpoint answers non-2xx. This line in fetchPaginatedComments fires when GET /posts/:commentable_id/comments (custom_domain_post_comments_path with purchase_id and page) returns an error status. Because the shared request() wrapper already converts 5xx, 429, aborts, and network failures into their own error types before this line runs, reaching line 112 in practice means a 4xx: post gone (404), purchase_id no longer granting access (401/403), or a malformed request (400/422).

Source

Thrown at app/javascript/data/comments.ts:112

  return typia.assert<{ deleted_comment_ids: string[] }>(json).deleted_comment_ids;
};

type FetchPaginatedCommentsArgs = {
  commentable_id: string;
  purchase_id: null | string;
  page: null | number;
};
export const fetchPaginatedComments = async ({
  commentable_id,
  purchase_id,
  page,
}: FetchPaginatedCommentsArgs): Promise<PaginatedComments> => {
  const response = await request({
    method: "GET",
    accept: "json",
    url: Routes.custom_domain_post_comments_path(commentable_id, { purchase_id, page }),
  });
  if (!response.ok) throw new ResponseError();
  return typia.assert<PaginatedComments>(await response.json());
};

View on GitHub (pinned to afeacbd394)

Solutions

  1. Open DevTools → Network and inspect the failing /comments request — the status code narrows it immediately (404 vs 403 vs 422).
  2. 404: the post no longer exists — stop rendering the comment thread and show an empty/unavailable state instead of retrying.
  3. 401/403: the purchase_id no longer grants access — send the reader to re-authenticate or repurchase rather than showing a generic failure.
  4. 422/400: log the purchase_id/page values actually sent and normalize page to null | number before calling fetchPaginatedComments.
Defensive patterns

Strategy: try-catch

Validate before calling

const ok =
  typeof commentable_id === "string" && commentable_id.length > 0 &&
  typeof purchase_id === "string" && purchase_id.length > 0 &&
  (page === null || (Number.isInteger(page) && page >= 1));
if (!ok) throw new Error("Comment thread is missing a post or purchase reference.");
await fetchPaginatedComments({ commentable_id, purchase_id, page });

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 comments = await fetchPaginatedComments({ commentable_id, purchase_id, page });
} catch (e) {
  assertResponseError(e);
  setCommentsUnavailable(); // render an empty state, do not break the post page
}

Prevention

When it happens

Trigger: Loading a post's comments with a purchase_id that was refunded or revoked so the access check fails; the commentable post was unpublished/deleted after the page rendered; the reader's session expired on a custom-domain post; passing page as NaN or a string because it was never normalized from the URL query.

Common situations: Reader tabs left open overnight while the post is deleted or the purchase refunded; custom-domain proxies/CDNs returning 404 for moved posts; hand-built comment URLs with wrong ids; permalink changes leaving stale commentable ids in cached pages.

Related errors


AI-assisted analysis of antiwork/gumroad@afeacbd394 (2026-08-21). Data as JSON: /api/errors/26d52305533b51df. Report an issue: GitHub.