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
- Check the Network tab for the PUT sections_link status: 404 means stale permalink — reload the editor; 422 means an invalid section order/id.
- Reload the page after a failure so the UI order re-syncs with the server (the current code leaves them diverged).
- Guard the -1 findIndex case before splicing (see defense).
- On 422, re-fetch the section list to reconcile ids that may have changed server-side.
- 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
- Guard mainIndex === -1 before splice — splice(-1, 1) removes the LAST section, corrupting the order you send.
- Roll back the optimistic setSections on failure; without it the UI keeps an unsaved order until reload.
- Build the URL from a permalink fetched at save time when multiple tabs may edit the product.
- On 404, prompt a reload — the permalink changed under you and every subsequent save will fail too.
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
- Could not add this passkey. Please try again.
- The banner could not be hidden. Check your connection and tr
- Sorry, something went wrong. Please try again.
- Something went wrong.
- Something went wrong.
AI-assisted analysis of antiwork/gumroad@afeacbd394 (2026-08-21).
Data as JSON: /api/errors/c8a2f4fda0aae668.
Report an issue: GitHub.