pbakaus/impeccable · warning
[impeccable] Could not read source to check the variant wrap
Error message
[impeccable] Could not read source to check the variant wrapper; keeping the session:
What it means
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.
Source
Thrown at skill/scripts/live-browser.js:6265
injectVariantsFromSource(filePath, sessionId, { ...opts, _orphanAttempt: attempt + 1 });
}, COMPLETED_SOURCE_FALLBACK_RETRY_MS);
};
// Discarding is durable (the session moves to the discarded phase and the
// picker replaces it), so it needs evidence that the wrapper is gone: a
// read that answers without the marker, or a 404 (the file itself was
// renamed or deleted). Either kind retries on the shared budget first.
// A read that fails for any other reason (the server briefly away, a
// transient fetch error) says nothing about the wrapper; after the budget
// the session is kept, the user told, and the next event retries.
const onNoWrapper = (reason) => {
if (!stillActive()) return;
if (attempt < COMPLETED_SOURCE_FALLBACK_RETRIES) { retryLater(); return; }
discardOrphanedSession(reason);
};
const onUnreadable = (detail) => {
if (!stillActive()) return;
if (attempt < COMPLETED_SOURCE_FALLBACK_RETRIES) { retryLater(); return; }
console.warn('[impeccable] Could not read source to check the variant wrapper; keeping the session: ' + detail);
showToast('Could not read the source file to check this session; it stays open and is checked again on the next event.', 5500);
};
fetch(url)
.then(r => { if (!r.ok) throw new Error('source read failed: ' + r.status); return r.text(); })
.then(text => {
if (!stillActive()) return;
if (sourceHasSessionWrapper(text, sessionId)) return;
onNoWrapper('variant wrapper missing from source');
})
.catch(err => {
const detail = err && err.message ? err.message : 'fetch failed';
if (/source read failed: 404$/.test(detail)) {
onNoWrapper('source file missing (404) while checking for the variant wrapper');
return;
}
onUnreadable(detail);
});
}View on GitHub (pinned to 2bc2879276)
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.
Defensive patterns
Strategy: retry
Validate before calling
const url = 'http://localhost:' + PORT + '/source?token=' + TOKEN + '&path=' + encodeURIComponent(filePath);
// pre-check reachability before trusting a read failure as conclusive
const reachable = await fetch(url, { method: 'HEAD' }).then(r => r.ok).catch(() => false); Try / catch
fetch(url)
.then(r => { if (!r.ok) throw new Error('source read failed: ' + r.status); return r.text(); })
.catch(err => {
// non-conclusive: keep the session, recheck on the next event
console.warn('could not read source; keeping session:', err.message);
}); Prevention
- 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'.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- ${String(res.status)}
- source read failed: ${r.status}
- TypeError: fetch failed: {}
- [impeccable] failed to fetch pending count:
- [impeccable] Discarding orphaned session
AI-assisted analysis of pbakaus/impeccable@2bc2879276 (2026-09-08).
Data as JSON: /api/errors/eaba3f58437cdc63.
Report an issue: GitHub.