antiwork/gumroad · error · ResponseError

Sorry, something went wrong. Please try again.

Error message

Sorry, something went wrong. Please try again.

What it means

Generic fallback shown when renaming a passkey in Gumroad's settings fails. handleRename PATCHes Routes.settings_passkey_path(passkey.id) with { nickname } and typia-asserts the JSON body; it throws ResponseError with the server's error_message when !response.ok, success is false, or the updated passkey object is missing. The literal 'Sorry, something went wrong. Please try again.' (GENERIC_ERROR) appears only when the server sent no error_message — or when the body failed the typia.assert shape check (e.g. an HTML error/redirect page), since the catch substitutes GENERIC_ERROR for any non-ResponseError exception.

Source

Thrown at app/javascript/components/Settings/PasswordPage/PasskeysSection.tsx:71

    const nickname = editingNickname.trim();
    if (!nickname || nickname === passkey.nickname) {
      setEditingId(null);
      return;
    }

    setSavingRename(true);
    try {
      const response = await request({
        url: Routes.settings_passkey_path(passkey.id),
        method: "PATCH",
        accept: "json",
        data: { nickname },
      });
      const result = typia.assert<{ success: boolean; passkey?: Passkey; error_message?: string }>(
        await response.json(),
      );
      if (!response.ok || !result.success || !result.passkey) {
        throw new ResponseError(result.error_message ?? GENERIC_ERROR);
      }

      const updated = result.passkey;
      setPasskeys((current) => current.map((item) => (item.id === updated.id ? updated : item)));
      setEditingId(null);
    } catch (e) {
      showAlert(e instanceof ResponseError ? e.message : GENERIC_ERROR, "error");
    } finally {
      setSavingRename(false);
    }
  });

  const handleConfirmDelete = asyncVoid(async () => {
    if (!pendingDeletion) return;

    setDeleting(true);
    try {
      const response = await request({

View on GitHub (pinned to afeacbd394)

Solutions

  1. Reload the settings page and retry — this refreshes the session and CSRF token.
  2. Confirm the passkey still appears in the list; if it vanished, it was deleted elsewhere and the rename target no longer exists.
  3. Inspect the PATCH response in the network tab: an HTML body means the request was redirected to login rather than a rename failure.
  4. If you control the endpoint, always return { success: false, error_message: '...' } on failure so users see the real reason instead of GENERIC_ERROR.

Example fix

# Rails controller, before
render json: { success: false }, status: :unprocessable_entity
# after — client shows the real reason instead of GENERIC_ERROR
render json: { success: false, error_message: "Nickname can't be blank." }, status: :unprocessable_entity
Defensive patterns

Strategy: try-catch

Type guard

const isPasskeyMutationFailure = (
  response: Response,
  result: { success?: boolean; passkey?: Passkey | null },
): boolean => !response.ok || result.success !== true || result.passkey == null;

Try / catch

try {
  const response = await request({ url: Routes.settings_passkey_path(passkey.id), method: "PATCH", accept: "json", data: { nickname } });
  const result = typia.assert<{ success: boolean; passkey?: Passkey; error_message?: string }>(await response.json());
  if (!response.ok || !result.success || !result.passkey) {
    throw new ResponseError(result.error_message ?? GENERIC_ERROR);
  }
} catch (e) {
  showAlert(e instanceof ResponseError ? e.message : GENERIC_ERROR, "error");
} finally {
  setSavingRename(false);
}

Prevention

When it happens

Trigger: PATCH /settings/passkeys/:id returns 401/419/422/500 without an error_message key; the session expired so the response is a login redirect (HTML) and typia.assert throws instead; controller-side nickname validation fails; or success:true comes back without the passkey object.

Common situations: Settings tab left open past session expiry (Rails authenticity token now invalid, 422 CSRF), the passkey deleted in another tab so the id no longer exists, a deployed API change renaming fields and breaking the typia contract, or a server 500 with an empty JSON body.

Related errors


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