pbakaus/impeccable · warning

[impeccable] some copy edits failed:

Error message

[impeccable] some copy edits failed:

What it means

After applying the stashed manual (copy) edits, the server result reported one or more failed edits. The script warns with the failed list, shows a toast with applied/failed counts, and updates the pending counter to the remaining edits.

Source

Thrown at skill/scripts/live-browser.js:4138

    setPendingApplyLoading(true, count);
    try {
      const res = await fetch(
        'http://localhost:' + PORT + '/manual-edit-commit?token=' + encodeURIComponent(TOKEN) + '&pageUrl=' + encodeURIComponent(location.pathname) + '&async=1',
        { method: 'POST', keepalive: true },
      );
      if (!res.ok) {
        const errBody = await res.json().catch(() => ({}));
        throw new Error(errBody.error || ('HTTP ' + res.status));
      }
      const result = await res.json();
      if (res.status === 202 || result.status === 'started') {
        waitForSseCompletion = true;
        return;
      }
      const remaining = remainingManualEditCount(result);
      updatePendingCounter(remaining);
      if (result.failed && result.failed.length > 0) {
        console.warn('[impeccable] some copy edits failed:', result.failed);
        showToast('Applied ' + (result.applied?.length || 0) + ', ' + result.failed.length + ' failed - see console', 5000);
      } else {
        const n = Array.isArray(result.applied) ? result.applied.length : (result.cleared || 0);
        if (n > 0) {
          showToast('Applied ' + n + ' edit' + (n === 1 ? '' : 's'), 2500);
        } else {
          console.warn('[impeccable] apply returned no verified edits:', result);
          showToast('No edits applied - see console', 4000);
        }
      }
    } catch (err) {
      console.error('[impeccable] commit failed:', err);
      showToast('Apply failed - see console', 4000);
    } finally {
      if (waitForSseCompletion) return;
      const remainingCount = parseInt(pendingPillEl?.dataset.count || '0', 10) || 0;
      if (remainingCount > 0) setPendingApplyLoading(false);
      else hidePendingApplyDock();

View on GitHub (pinned to 2bc2879276)

Solutions

  1. Open the browser console and inspect the logged result.failed array for the specific failed edits.
  2. Re-apply the remaining edits via the pending pill after the page settled (counter shows what is left).
  3. If edits are stale after a re-render, re-create the affected copy edits and clear the stash.
  4. Reload the page and retry if anchors are temporarily missing due to HMR.

Example fix

// before (failures only visible in console)
console.warn('[impeccable] some copy edits failed:', result.failed);
// after (defensive: skip edits whose target vanished)
const failed = result.failed.filter(f => f.reason !== 'target-missing');
console.warn('[impeccable] some copy edits failed:', failed.length ? failed : 'none actionable');
Defensive patterns

Strategy: fallback

Validate before calling

function editsTargetLiveNodes(result) {
  return result.failed.every(f => document.querySelector(f.selector ?? '[data-impeccable-edit]') !== null);
}

Try / catch

if (result.failed && result.failed.length > 0) {
  console.warn('[impeccable] some copy edits failed:', result.failed);
  showToast('Applied ' + (result.applied?.length || 0) + ', ' + result.failed.length + ' failed - see console', 5000);
}

Prevention

When it happens

Trigger: onPendingPillClick applies manual edits; the response's result.failed array is non-empty, triggering the warn at skill/scripts/live-browser.js:4138 and a 5s toast 'Applied N, M failed - see console'.

Common situations: A copy edit targets a text node that no longer exists (page re-rendered since stashing); edit selector/anchor became stale after framework re-render; server-side edit application rejected an ambiguous match.

Related errors


AI-assisted analysis of pbakaus/impeccable@2bc2879276 (2026-09-08). Data as JSON: /api/errors/19f8371b756fba29. Report an issue: GitHub.