{"record":{"id":"d9c6554a8ac4d3b8","repo":"pbakaus/impeccable","slug":"impeccable-failed-to-fetch-pending-count","errorCode":null,"errorMessage":"[impeccable] failed to fetch pending count:","messagePattern":"\\[impeccable\\] failed to fetch pending count:","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"skill/scripts/live-browser.js","lineNumber":4090,"sourceCode":"    if (previousCount <= 0) playPendingIntroAnimation();\n  }\n\n  function maybeShowFirstSaveToast() {\n    if (!firstSaveOfSession) return;\n    firstSaveOfSession = false;\n    showToast('Saved. Click \"Apply copy edits\" to write changes.', 4500);\n  }\n\n  async function fetchPendingCount() {\n    try {\n      const res = await fetch(\n        'http://localhost:' + PORT + '/manual-edit-stash?token=' + encodeURIComponent(TOKEN) + '&pageUrl=' + encodeURIComponent(location.pathname),\n      );\n      if (!res.ok) return;\n      const data = await res.json();\n      updatePendingCounter(data.count || 0);\n    } catch (err) {\n      console.warn('[impeccable] failed to fetch pending count:', err);\n    }\n  }\n\n  async function onPendingPillClick() {\n    const count = parseInt(pendingPillEl?.dataset.count || '0', 10);\n    if (count <= 0 || pendingApplyInFlight) return;\n    const ok = confirm('Apply ' + count + ' copy edit' + (count === 1 ? '' : 's') + ' to source?');\n    if (!ok) return;\n    let waitForSseCompletion = false;\n    resetManualApplyProgress(count);\n    setPendingApplyLoading(true, count);\n    try {\n      const res = await fetch(\n        'http://localhost:' + PORT + '/manual-edit-commit?token=' + encodeURIComponent(TOKEN) + '&pageUrl=' + encodeURIComponent(location.pathname) + '&async=1',\n        { method: 'POST', keepalive: true },\n      );\n      if (!res.ok) {\n        const errBody = await res.json().catch(() => ({}));","sourceCodeStart":4072,"sourceCodeEnd":4108,"githubUrl":"https://github.com/pbakaus/impeccable/blob/f88b2837a7d7c3182e46307bbbb091a1ed547571/skill/scripts/live-browser.js#L4072-L4108","documentation":"The on-page client polls GET /manual-edit-stash?token=...&pageUrl=... on the local live server to keep the pending-edits pill count current. Any network-level rejection of that fetch (server not listening, wrong port, connection reset) is caught and logged as 'failed to fetch pending count:'; the pill simply keeps its last known count. Note a 401 does not produce this log — !res.ok returns silently.","triggerScenarios":"The live server was stopped or crashed; the page holds a stale PORT after the server moved; a proxy or firewall intercepts localhost requests; the machine's loopback is unavailable.","commonSituations":"Dev server exited while its injected page stayed open; server restarted on a different port and the old tab still polls the dead one; corporate proxy env vars routing localhost through a proxy.","solutions":["Restart the live server (the impeccable serve/dev command) and reload the page so PORT and TOKEN refresh","Confirm the port the page is fetching matches the running server's output","Set NO_PROXY=localhost,127.0.0.1 if a system proxy intercepts loopback fetches"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Health-check the server before relying on pending-count polling\nconst ok = await fetch(`http://localhost:${PORT}/status?token=${encodeURIComponent(TOKEN)}`).then((r) => r.ok).catch(() => false);\nif (!ok) { promptServerRestart(); return; }","typeGuard":null,"tryCatchPattern":"try { /* fetch pending count */ } catch (err) { console.warn(err); /* keep last count; next poll interval retries */ }","preventionTips":["Restart the live server before debugging page-side polling failures","After a server restart, reload the page so PORT/TOKEN match the new instance","Exclude localhost from system proxies (NO_PROXY) in dev environments"],"tags":["fetch","network","localhost","dev-server","polling"],"backgroundTag":"connection-refused","analyzedSha":"f88b2837a7d7c3182e46307bbbb091a1ed547571","analyzedAt":"2026-08-18T04:58:36.608Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}