pbakaus/impeccable · warning
[impeccable] skipped unsafe copy edit DOM restore for
Error message
[impeccable] skipped unsafe copy edit DOM restore for
What it means
When the user discards pending copy edits, the script tries to restore each edit's original text back into the page DOM. This warning counts elements it refused to restore because it was unsafe: the target element was not found, lacked originalText, still had child elements, or its current text did not match the edit's recorded newText (i.e. the DOM changed since the edit). The page DOM may remain visually edited until a refresh.
Source
Thrown at skill/scripts/live-browser.js:4362
fetchPendingCount();
}
}
function restoreDiscardedManualEdits(entries) {
let failures = 0;
for (const entry of entries || []) {
for (const op of entry.ops || []) {
if (restoreMixedTextNodeManualEdit(op)) continue;
const el = findManualEditRestoreElement(op);
if (!el || typeof op.originalText !== 'string' || !canRestoreManualEditElement(el, op)) {
failures += 1;
continue;
}
el.textContent = op.originalText;
}
}
if (failures > 0) {
console.warn('[impeccable] skipped unsafe copy edit DOM restore for', failures, 'edit(s). Refresh to reset the page DOM.');
}
return failures;
}
function canRestoreManualEditElement(el, op) {
if (!el || typeof op?.originalText !== 'string') return false;
if (el.children && el.children.length > 0) return false;
return normalizeManualContextText(el.textContent) === normalizeManualContextText(op.newText);
}
function mixedTextWrapRestoreHint(el) {
if (!el || !el.dataset || el.dataset.impeccableTextWrap !== 'true' || !el.parentElement) return null;
const siblings = directMixedTextRestoreNodes(el.parentElement);
const textIndex = siblings.indexOf(el);
return {
kind: 'mixedTextNode',
parentRef: documentRefForElement(el.parentElement),
textIndex,View on GitHub (pinned to 2bc2879276)
Solutions
- Refresh the page — that resets the DOM to match the source, which is the documented remedy in the message itself.
- Before discarding, avoid navigating or letting HMR re-render the edited elements.
- If restores routinely fail, re-pick elements after any re-render rather than accumulating edits across renders.
- Verify the edits are leaf text nodes (no child elements), which are the only ones safely restorable.
Defensive patterns
Strategy: type-guard
Type guard
function canRestoreManualEditElement(el, op) {
if (!el || typeof op?.originalText !== 'string') return false;
if (el.children && el.children.length > 0) return false; // leaf nodes only
return normalize(el.textContent) === normalize(op.newText);
} Prevention
- Discard edits before navigating, closing modals, or triggering re-renders.
- Edit only leaf text elements; containers with children cannot be safely restored.
- Refresh the page after discarding if the toast reports skipped restores.
- Avoid stacking multiple edits on the same element between discards.
When it happens
Trigger: Clicking the trash/pending-pill discard action after the page DOM changed — the edited element was re-rendered by the framework, its text was edited again, it now contains child nodes, or canRestoreManualEditElement returns false for one or more stashed ops.
Common situations: Framework re-render or HMR replaced the edited node between edit and discard; the user edited an element whose text subsequently changed; edits made in one route/component, discard attempted after navigation; nested-element edits that fail the leaf-only safety check.
Related errors
- [impeccable] scan failed
- [impeccable] Svelte component abort cleanup failed:
- [impeccable] Svelte component reset cleanup failed:
- [impeccable] apply returned no verified edits:
- [impeccable] Could not find original element in live DOM.
AI-assisted analysis of pbakaus/impeccable@2bc2879276 (2026-09-08).
Data as JSON: /api/errors/4f165a735e1d4120.
Report an issue: GitHub.