pbakaus/impeccable · warning

[impeccable] capture failed, proceeding without screenshot:

Error message

[impeccable] capture failed, proceeding without screenshot:

What it means

Before dispatching a generate/steer event, the client captures the target element to a PNG blob via captureElementToBlob. If that capture throws (modern-screenshot failure, tainted canvas, layout mid-transition), the error is logged as 'capture failed, proceeding without screenshot:' and the flow continues without the image: non-annotated events were already sent before capture, annotated ones are sent afterwards minus the screenshotPath.

Source

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

  async function captureAndEmit(el, basePayload, snapshot, rect) {
    const hasAnnotations = snapshot && (snapshot.comments.length > 0 || snapshot.strokes.length > 0);

    // Plain requests do not send a screenshot to the agent, so capture is
    // presentation-only. Wait only for the helper to accept the event before
    // starting CPU-heavy capture; this yields the browser task and prevents
    // rasterization from delaying the fetch itself.
    if (!hasAnnotations) {
      basePayload.clientSentAt = Date.now();
      await sendEvent(basePayload);
    }

    let screenshotPath;
    let blob;
    let paper;
    try {
      ({ blob, paper } = await captureElementToBlob(el, snapshot, rect));
    } catch (err) {
      console.warn('[impeccable] capture failed, proceeding without screenshot:', err);
    }
    // Light up the shader overlay the moment capture is ready - no reason to
    // wait for the upload to complete before the user sees something alive.
    if (blob && state === 'GENERATING') {
      showShaderOverlay(el, blob, rect, paper);
    }
    // Only upload + forward the screenshot when annotations (comments/strokes)
    // are present. Without annotations the image is pure visual anchoring -
    // it biases the model toward the current rendering and works against the
    // three-distinct-directions brief.
    if (blob && hasAnnotations) {
      try {
        const uploadRes = await fetch(
          'http://localhost:' + PORT + '/annotation?token=' + encodeURIComponent(TOKEN) +
          '&eventId=' + encodeURIComponent(basePayload.id),
          { method: 'POST', headers: { 'Content-Type': 'image/png' }, body: blob },
        );
        if (uploadRes.ok) {

View on GitHub (pinned to f88b2837a7)

Solutions

  1. Check the request still succeeded — the event goes through without the screenshot
  2. Retrigger the generate to get a screenshot-backed run if visual anchoring mattered
  3. Serve images/fonts with permissive CORS so the canvas is not tainted
Defensive patterns

Strategy: fallback

Validate before calling

if (!el.isConnected) { sendWithoutScreenshot(); return; } // capture is pointless on detached elements

Try / catch

try { ({ blob, paper } = await captureElementToBlob(el, snapshot, rect)); } catch (err) { console.warn('capture failed', err); } // event still dispatched without screenshotPath

Prevention

When it happens

Trigger: modern-screenshot throws on the element (foreignObject-hostile content, cross-origin images without CORS, fonts still loading); capture racing a hot-reload remount of the target; capturing during page teardown.

Common situations: Dev-server hot reload swaps the element mid-capture; target contains cross-origin <img> without CORS headers; heavy pages where the rasterizer times out or OOMs.

Related errors


AI-assisted analysis of pbakaus/impeccable@f88b2837a7 (2026-08-18). Data as JSON: /api/errors/c1380f587c3db74d. Report an issue: GitHub.