antiwork/gumroad · error · ResponseError

Something went wrong.

Error message

Something went wrong.

What it means

Switching seller accounts from the nav: onClick preventDefaults the link and POSTs to sellers_switch_path(team_membership_id), expecting a redirect back to the current URL with account_switched=true appended (so Pundit-driven redirects to the dashboard do not show an error). A non-ok response throws a bare ResponseError, caught and reported as 'Something went wrong.' — the page does not navigate.

Source

Thrown at app/javascript/components/Nav.tsx:221

  return <section className={classNames("mb-4 hidden lg:grid", { grid: isOpen })}>{children}</section>;
};

export const NavLinkDropdownMembershipItem = ({ teamMembership }: { teamMembership: TeamMembership }) => {
  const onClick = (ev: React.MouseEvent<HTMLAnchorElement>) => {
    const currentUrl = new URL(window.location.href);
    // It is difficult to tell if the account to be switched has access to the current page via policies in this context.
    // Pundit deals with that, and PunditAuthorization concern handles Pundit::NotAuthorizedError.
    // account_switched param is solely for the purpose of not showing the error message when redirecting to the
    // dashboard in case the user doesn't have access to the page.
    currentUrl.searchParams.set("account_switched", "true");
    ev.preventDefault();
    request({
      method: "POST",
      accept: "json",
      url: Routes.sellers_switch_path({ team_membership_id: teamMembership.id }),
    })
      .then((res) => {
        if (!res.ok) throw new ResponseError();
        window.location.href = currentUrl.toString();
      })
      .catch((e: unknown) => {
        assertResponseError(e);
        showAlert("Something went wrong.", "error");
      });
  };

  return (
    <MenuItemRadio checked={teamMembership.is_selected} asChild>
      <a href={Routes.sellers_switch_path()} onClick={onClick} className="min-w-0">
        <Avatar src={teamMembership.seller_avatar_url} alt={teamMembership.seller_name} />
        <span className="min-w-0 flex-1 truncate" title={teamMembership.seller_name}>
          {teamMembership.seller_name}
        </span>
        {teamMembership.is_selected ? <CheckCircle pack="filled" className="size-5 h-5 shrink-0 text-accent" /> : null}
      </a>
    </MenuItemRadio>

View on GitHub (pinned to afeacbd394)

Solutions

  1. Check the Network tab for the sellers_switch POST status: 401 points at the session, 403/404 at the membership.
  2. If 401, reload — a fresh page re-authenticates and re-renders the nav without stale memberships.
  3. If 404 after a deploy, hard-refresh to pick up the new JS bundle with current routes.
  4. Verify the membership still exists and is active in the admin console.
  5. After a successful switch, ensure the redirect keeps the account_switched param so unrelated Pundit denials stay silent.

Example fix

// before
.then((res) => {
  if (!res.ok) throw new ResponseError();
  window.location.href = currentUrl.toString();
})

// after — a dead session should send the user to re-auth, not show a dead-end alert
.then((res) => {
  if (res.status === 401) { window.location.href = Routes.login_path(); return; }
  if (!res.ok) throw new ResponseError();
  window.location.href = currentUrl.toString();
})
Defensive patterns

Strategy: try-catch

Type guard

const isResponseError = (e: unknown): e is ResponseError => e instanceof ResponseError;

Try / catch

.catch((e: unknown) => {
  assertResponseError(e);
  if (needsReauth) { window.location.href = Routes.login_path(); return; } // 401: alert is a dead end
  showAlert('Something went wrong.', 'error');
});

Prevention

When it happens

Trigger: POST sellers_switch_path returning 401 (session expired), 403/404 (team membership revoked or inactive since the nav rendered), or a route change after a deploy — the .then sees !res.ok and throws.

Common situations: Membership revoked in another tab/admin while the nav still lists the team; long-lived tab with a dead session; deploy renaming the switch route while cached JS keeps the old URL.

Related errors


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