{"record":{"id":"eaba3f58437cdc63","repo":"pbakaus/impeccable","slug":"impeccable-could-not-read-source-to-check-the-va","errorCode":null,"errorMessage":"[impeccable] Could not read source to check the variant wrapper; keeping the session: ","messagePattern":"\\[impeccable\\] Could not read source to check the variant wrapper; keeping the session: ","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"skill/scripts/live-browser.js","lineNumber":6265,"sourceCode":"        injectVariantsFromSource(filePath, sessionId, { ...opts, _orphanAttempt: attempt + 1 });\n      }, COMPLETED_SOURCE_FALLBACK_RETRY_MS);\n    };\n    // Discarding is durable (the session moves to the discarded phase and the\n    // picker replaces it), so it needs evidence that the wrapper is gone: a\n    // read that answers without the marker, or a 404 (the file itself was\n    // renamed or deleted). Either kind retries on the shared budget first.\n    // A read that fails for any other reason (the server briefly away, a\n    // transient fetch error) says nothing about the wrapper; after the budget\n    // the session is kept, the user told, and the next event retries.\n    const onNoWrapper = (reason) => {\n      if (!stillActive()) return;\n      if (attempt < COMPLETED_SOURCE_FALLBACK_RETRIES) { retryLater(); return; }\n      discardOrphanedSession(reason);\n    };\n    const onUnreadable = (detail) => {\n      if (!stillActive()) return;\n      if (attempt < COMPLETED_SOURCE_FALLBACK_RETRIES) { retryLater(); return; }\n      console.warn('[impeccable] Could not read source to check the variant wrapper; keeping the session: ' + detail);\n      showToast('Could not read the source file to check this session; it stays open and is checked again on the next event.', 5500);\n    };\n    fetch(url)\n      .then(r => { if (!r.ok) throw new Error('source read failed: ' + r.status); return r.text(); })\n      .then(text => {\n        if (!stillActive()) return;\n        if (sourceHasSessionWrapper(text, sessionId)) return;\n        onNoWrapper('variant wrapper missing from source');\n      })\n      .catch(err => {\n        const detail = err && err.message ? err.message : 'fetch failed';\n        if (/source read failed: 404$/.test(detail)) {\n          onNoWrapper('source file missing (404) while checking for the variant wrapper');\n          return;\n        }\n        onUnreadable(detail);\n      });\n  }","sourceCodeStart":6247,"sourceCodeEnd":6283,"githubUrl":"https://github.com/pbakaus/impeccable/blob/2bc2879276c1f321a53c4ca99d3371e411329b52/skill/scripts/live-browser.js#L6247-L6283","documentation":"During the orphan probe, the script fetches the session's source file via the local /source endpoint to check whether the variant wrapper still exists. When the read itself fails for a non-conclusive reason — the server briefly unavailable, a transient fetch error, or a non-404 HTTP error — after exhausting the 3-retry budget it logs this warning but deliberately KEEPS the session, because an unreadable file says nothing about whether the wrapper is gone. A toast tells the user the check will re-run on the next event.","triggerScenarios":"fetch of http://localhost:PORT/source?token=...&path=... fails (network/TypeError) or returns a non-OK status other than a conclusive 404, on every retry attempt (attempt >= COMPLETED_SOURCE_FALLBACK_RETRIES === 3) while the session is active.","commonSituations":"The live server was restarting mid-check; the dev machine slept or the port changed; a proxy or service worker intercepted the fetch; token/appRoot mismatch causing repeated auth-style failures rather than 404.","solutions":["Do nothing destructive — the session is intentionally kept and rechecked on the next event.","Verify the live server is running on the expected port (restart the live server if it was mid-restart).","Check the /source endpoint URL, token, and file path by fetching it manually from the page context.","Disable interfering service workers or proxies on localhost during live mode."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"const url = 'http://localhost:' + PORT + '/source?token=' + TOKEN + '&path=' + encodeURIComponent(filePath);\n// pre-check reachability before trusting a read failure as conclusive\nconst reachable = await fetch(url, { method: 'HEAD' }).then(r => r.ok).catch(() => false);","typeGuard":null,"tryCatchPattern":"fetch(url)\n  .then(r => { if (!r.ok) throw new Error('source read failed: ' + r.status); return r.text(); })\n  .catch(err => {\n    // non-conclusive: keep the session, recheck on the next event\n    console.warn('could not read source; keeping session:', err.message);\n  });","preventionTips":["Keep the live server running and avoid restarting it mid-session.","Prevent machine sleep during live sessions.","Disable service workers/proxies on localhost while using live mode.","Remember 404 (file gone) is treated as conclusive; other failures only mean 'unknown'."],"tags":["network","fetch","source-file","session","transient"],"backgroundTag":"http-request-failed","analyzedSha":"2bc2879276c1f321a53c4ca99d3371e411329b52","analyzedAt":"2026-09-08T04:51:14.109Z","contentChangedAt":"2026-09-08T04:51:14.109Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}