pbakaus/impeccable · error · Error
HTTP ${res.status}
Error message
HTTP ${res.status} What it means
Discarding manual edits POSTs to /manual-edit-discard; on a non-OK response the code throws Error('HTTP ' + res.status). Unlike the commit paths, this one does not parse the response body for a server error message, so you only get the status code.
Source
Thrown at skill/scripts/live-browser.js:4170
} finally {
if (waitForSseCompletion) return;
const remainingCount = parseInt(pendingPillEl?.dataset.count || '0', 10) || 0;
if (remainingCount > 0) setPendingApplyLoading(false);
else hidePendingApplyDock();
}
}
async function onPendingTrashClick() {
const count = parseInt(pendingPillEl?.dataset.count || '0', 10);
if (count <= 0 || pendingApplyInFlight) return;
const ok = confirm('Discard ' + count + ' copy edit' + (count === 1 ? '' : 's') + ' on this page?');
if (!ok) return;
try {
const res = await fetch(
'http://localhost:' + PORT + '/manual-edit-discard?token=' + encodeURIComponent(TOKEN) + '&pageUrl=' + encodeURIComponent(location.pathname),
{ method: 'POST' },
);
if (!res.ok) throw new Error('HTTP ' + res.status);
const result = await res.json().catch(() => ({}));
const restoreFailures = restoreDiscardedManualEdits(result.entries || []);
updatePendingCounter(0);
if (restoreFailures > 0) {
showToast('Discarded ' + count + ' copy edit' + (count === 1 ? '' : 's') + ' - refresh to reset ' + restoreFailures, 4000);
} else {
showToast('Discarded ' + count + ' copy edit' + (count === 1 ? '' : 's'), 2500);
}
} catch (err) {
console.error('[impeccable] discard failed:', err);
showToast('Discard failed - see console', 4000);
}
}
function showManualApplyDecision(msg) {
const count = parseInt(pendingPillEl?.dataset.count || '0', 10) || numberOrNull(msg?.remainingCount) || 0;
pendingApplyInFlight = false;
storeManualApplyState(count, {View on GitHub (pinned to 2bc2879276)
Solutions
- Note the status: 401/403 implies token mismatch — refresh the page to re-handshake
- Check the dev-server logs for the /manual-edit-discard request failure
- Retry the discard after refreshing; edits remain applied so nothing is lost
- Re-run the live session if the server state has diverged
Example fix
// before
if (!res.ok) throw new Error('HTTP ' + res.status);
// after
if (!res.ok) {
const errBody = await res.json().catch(() => ({}));
throw new Error(errBody.error || ('HTTP ' + res.status));
} Defensive patterns
Strategy: try-catch
Validate before calling
async function discardIsSafe(port, token, pageUrl) {
const res = await fetch('http://localhost:' + port + '/state?token=' + token);
return res.ok; // server session alive before discarding
} Try / catch
try {
const res = await fetch(discardUrl, { method: 'POST' });
if (!res.ok) throw new Error('HTTP ' + res.status);
} catch (e) {
showToast('Discard failed: ' + e.message + ' - refresh to re-sync', 4000);
} Prevention
- Re-handshake (page refresh) whenever the dev server restarted
- Check the pending counter is non-zero before discarding
- Retry once on transient 5xx before showing a failure toast
When it happens
Trigger: Clicking discard (trash) on pending copy edits while the dev server returns 4xx/5xx — e.g. stale token or unknown pageUrl.
Common situations: Dev server restarted (token mismatch); the pending-edit list changed server-side; transient server error during teardown.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- errBody.error || ('HTTP ' + res.status)
- ${String(res.status)}
- source read failed: ${r.status}
- ${r.status}
- TypeError: fetch failed: {}
AI-assisted analysis of pbakaus/impeccable@2bc2879276 (2026-09-08).
Data as JSON: /api/errors/d1f29ee8f77bdc58.
Report an issue: GitHub.