pbakaus/impeccable · warning

[impeccable] Discarding orphaned session

Error message

[impeccable] Discarding orphaned session 

What it means

This is the terminal self-discard path for an orphaned live session: the session's source-side scaffolding (the data-impeccable-variants wrapper) no longer exists in the source file, so no reload, HMR push, or server restart can ever complete it. The script sends a discard event (marked orphaned), cleans up all chrome, and toasts that the session no longer matches the source. It is a deliberate recovery, not an unexpected crash.

Source

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

    if (message) showToast(message, 5000);
  }

  // How many delayed re-reads a completion-driven source fallback gets when
  // the fetched source still shows only the preflight scaffold, before the
  // failure is surfaced via recoverEmptyCycling.
  const COMPLETED_SOURCE_FALLBACK_RETRIES = 3;
  const COMPLETED_SOURCE_FALLBACK_RETRY_MS = 1200;

  /**
   * Terminal recovery for a session whose source-side scaffolding no longer
   * exists. The discard event is best-effort: with no agent polling it parks
   * the durable session in discard_requested, which no resume path adopts;
   * with an agent attached it triggers the normal discard finalization.
   */
  function discardOrphanedSession(reason) {
    const sessionId = currentSessionId;
    if (!sessionId) return;
    console.warn('[impeccable] Discarding orphaned session ' + sessionId + ': ' + reason);
    sendEvent({ type: 'discard', id: sessionId, orphaned: true }).catch(() => {});
    markSessionHandled();
    cleanup({ instantChrome: true });
    showToast('The previous live session no longer matches the source file, so it was discarded. Pick an element to start fresh.', 6000);
  }

  function isJsxSourceFile(filePath) {
    return /\.[cm]?[jt]sx$/i.test(String(filePath || ''));
  }

  function sourceHasSessionWrapper(text, sessionId) {
    const src = String(text || '');
    return src.indexOf('data-impeccable-variants="' + sessionId + '"') !== -1
      || src.indexOf("data-impeccable-variants='" + sessionId + "'") !== -1
      || src.indexOf('impeccable-variants-start ' + sessionId) !== -1;
  }

  /**

View on GitHub (pinned to 2bc2879276)

Solutions

  1. Pick an element again to start a fresh session — the old one was intentionally discarded and cannot be recovered.
  2. If the discard was wrong, restore the file version that contains the impeccable-variants markers (e.g. git checkout the file) before retrying.
  3. Avoid editing or regenerating the target source file while a live variant session is active.
  4. Ensure the agent attached to the live session is polling so discard finalization completes server-side.
Defensive patterns

Strategy: validation

Validate before calling

function sourceHasSessionWrapper(text, sessionId) {
  const src = String(text || '');
  return src.includes('data-impeccable-variants="' + sessionId + '"')
    || src.includes("data-impeccable-variants='" + sessionId + "'")
    || src.includes('impeccable-variants-start ' + sessionId);
}
// guard: only discard after the wrapper is confirmed absent
if (!sourceHasSessionWrapper(sourceText, sessionId)) discardOrphanedSession('wrapper missing');

Prevention

When it happens

Trigger: Reached from probeJsxWrapperForOrphan (JSX files) or the HTML source-read path when, after the COMPLETED_SOURCE_FALLBACK_RETRIES budget (3 retries x 1.2s), the source file still lacks the session wrapper or the file 404s — i.e. the file was edited, regenerated, renamed, or deleted out from under an active/resumed session.

Common situations: Agent rewrite or manual edit overwrote the source file mid-session; HMR regeneration dropped the wrapper; the user reverted the file with git; the file was renamed or deleted; resuming a saved session whose source has since changed.

Related errors


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