unslothai/unsloth · error
Delete failed (${res.status})
Error message
Delete failed (${res.status}) What it means
Thrown by deletePromptEntry when DELETE /api/prompts/entries/:id returns non-2xx. Unlike save/bulk (which route through parseJsonOrThrow), the delete path has no body parsing — only the numeric status is reported. The entry therefore remains in local state.
Source
Thrown at studio/frontend/src/features/chat/api/prompts-api.ts:48
export async function listPromptEntries(): Promise<PromptEntry[]> {
const res = await authFetch("/api/prompts/entries");
const data = await parseJsonOrThrow<{ entries: PromptEntry[] }>(res);
return data.entries;
}
export async function savePromptEntry(entry: PromptEntry): Promise<PromptEntry> {
const res = await authFetch(`/api/prompts/entries/${entry.id}`, {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(entry),
});
return parseJsonOrThrow<PromptEntry>(res);
}
export async function deletePromptEntry(id: string): Promise<void> {
const res = await authFetch(`/api/prompts/entries/${id}`, { method: "DELETE" });
if (!res.ok) throw new Error(`Delete failed (${res.status})`);
}
export async function bulkSavePromptEntries(entries: PromptEntry[]): Promise<number> {
if (!entries.length) return 0;
const res = await authFetch("/api/prompts/entries/bulk", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ entries }),
});
const data = await parseJsonOrThrow<{ count: number }>(res);
return data.count;
}
export async function listPromptLists(): Promise<PromptListEntry[]> {
const res = await authFetch("/api/prompts/lists");
const data = await parseJsonOrThrow<{ lists: PromptListEntry[] }>(res);
return data.lists;
}View on GitHub (pinned to 203007d190)
Solutions
- Re-auth if 401, retry after backend recovery if 5xx.
- On repeated failure, refresh the entries list and retry against fresh state.
- Consider treating 404 as success if the UX allows (pattern already used in providers deleteProviderConfig).
Example fix
// before
if (!res.ok) throw new Error(`Delete failed (${res.status})`);
// after
if (res.status === 404) return; // already deleted elsewhere
if (!res.ok) throw new Error(`Delete failed (${res.status})`); Defensive patterns
Strategy: fallback
Try / catch
try { await deletePromptEntry(id); }
catch (e) {
if (/\(404\)$/.test(e.message)) { removeEntryLocally(id); return; } // already gone
showError(e.message);
} Prevention
- Handle 404 as success for delete-by-id (matches providers-api pattern).
- Refresh entries before delete sweeps to avoid stale ids.
- Disable the delete button while a delete is in flight to avoid double submits.
When it happens
Trigger: Deleting a prompt entry that is concurrently deleted elsewhere (non-404 error), deleting with expired auth (401), or backend failure (5xx).
Common situations: Two tabs deleting the same entry where the server does not return 404-or-2xx for the loser; session expired before the delete click; backend restart mid-operation.
Related errors
- Request failed (${res.status})
- family {getattr(fam, 'name', fam)!r} declares no prequant_fi
- lockfile not found: {path}
- load timed out (last progress: {prog})
- deadline reached while pacing before {method} {_redact_url(u
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/39c227e717011001.
Report an issue: GitHub.