antiwork/gumroad · error · ResponseError

Something went wrong.

Error message

Something went wrong.

What it means

saveSections persists a reordered section list via PUT sections_link_path(permalink) with the ordered ids and main_section index. A non-ok response throws a bare ResponseError, caught and shown as 'Something went wrong.'. Crucially, setSections(sections) already ran optimistically and there is no rollback in the catch — the UI keeps the failed order until reload, silently diverging from the server. Also note the latent trap: when findIndex returns -1 (no unsaved/main section), splice(-1, 1) removes the LAST section instead of none.

Source

Thrown at app/javascript/components/Product/Layout.tsx:79

      header: "",
      hide_header: true,
    });
    return sections;
  });

  const saveSections = async (sections: EditableSection[]) => {
    setSections(sections);
    const order = sections.map((section) => section.id);
    const mainIndex = order.findIndex((id) => !id);
    order.splice(mainIndex, 1);
    try {
      const response = await request({
        method: "PUT",
        url: Routes.sections_link_path(product.permalink),
        accept: "json",
        data: { sections: order, main_section_index: mainIndex },
      });
      if (!response.ok) throw new ResponseError();
      showAlert("Changes saved!", "success");
    } catch (e) {
      assertResponseError(e);
      showAlert(e.message, "error");
    }
  };

  const sectionsRef = useRefToLatest(sections);
  const dispatch = (action: Action) => {
    const sections = sectionsRef.current;
    switch (action.type) {
      case "add-section": {
        action.section.then((section) => {
          const newSections = [...sections];
          newSections.splice(action.index, 0, section);
          void saveSections(newSections);
        }, assertResponseError);
        break;

View on GitHub (pinned to afeacbd394)

Solutions

  1. Check the Network tab for the PUT sections_link status: 404 means stale permalink — reload the editor; 422 means an invalid section order/id.
  2. Reload the page after a failure so the UI order re-syncs with the server (the current code leaves them diverged).
  3. Guard the -1 findIndex case before splicing (see defense).
  4. On 422, re-fetch the section list to reconcile ids that may have changed server-side.
  5. Surface a reload prompt in the alert so sellers know their drag was not saved.

Example fix

// before
const mainIndex = order.findIndex((id) => !id);
order.splice(mainIndex, 1);

// after — findIndex returning -1 made splice(-1, 1) silently drop the LAST section
const mainIndex = order.findIndex((id) => !id);
if (mainIndex === -1) throw new ResponseError('No main section found — reload the page.');
order.splice(mainIndex, 1);
Defensive patterns

Strategy: validation

Validate before calling

const order = sections.map((section) => section.id);
const mainIndex = order.findIndex((id) => !id);
if (mainIndex === -1) {
  showAlert('No main section found — reload the page and try again.', 'error');
  return; // guards the splice(-1, 1) trap that silently drops the last section
}

Type guard

const areSectionIds = (ids: unknown[]): ids is string[] => ids.every((id) => typeof id === 'string');

Try / catch

try {
  const response = await request({ method: 'PUT', url: Routes.sections_link_path(product.permalink), accept: 'json', data: { sections: order, main_section_index: mainIndex } });
  if (!response.ok) throw new ResponseError();
} catch (e) {
  assertResponseError(e);
  setSections(sectionsRef.current); // roll back the optimistic reorder so UI matches server
  showAlert('Changes could not be saved. Reload the page and try again.', 'error');
}

Prevention

When it happens

Trigger: PUT returning 404 (permalink renamed in another tab — the URL is built from a stale permalink), 401 (expired session), or 422 (an id in the order array the server does not accept, or main_section_index out of range).

Common situations: Two tabs editing the same product — one renames the permalink, the other's next drag-and-drop save 404s; a section deleted server-side between load and reorder; seller reorders while logged out in another tab.

Related errors


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