{"record":{"id":"51a0ea397bf4ea95","repo":"pbakaus/impeccable","slug":"impeccable-svelte-ancestor-crop-capture-failed","errorCode":null,"errorMessage":"[impeccable] Svelte ancestor crop capture failed, falling back to element capture:","messagePattern":"\\[impeccable\\] Svelte ancestor crop capture failed, falling back to element capture:","errorType":"console","errorClass":null,"httpStatus":null,"severity":"info","filePath":"skill/scripts/live-browser.js","lineNumber":7976,"sourceCode":"      if (pos === 'static') {\n        savedPosition = el.style.position;\n        el.style.position = 'relative';\n      }\n      annotNode = buildAnnotationsForCapture(rect, snapshot);\n      el.appendChild(annotNode);\n    }\n    try {\n      const ms = await loadModernScreenshot();\n      const fontCssText = await collectFontCssText();\n      const opts = {\n        scale: Math.min(window.devicePixelRatio || 1, 2),\n        font: fontCssText ? { cssText: fontCssText } : undefined,\n      };\n      if (shouldUseAncestorCropShaderProxy(el)) {\n        try {\n          return await hideCaptureChromeForShaderProxy(() => captureElementFromRenderedAncestor(ms, el, opts));\n        } catch (err) {\n          console.warn('[impeccable] Svelte ancestor crop capture failed, falling back to element capture:', err);\n        }\n      }\n      const bg = resolveCanvasBackground(el);\n      // Fast path: the element paints its own background, or an opaque ancestor\n      // color was found. modern-screenshot bakes that color; paper matches it.\n      if (bg !== '#ffffff') {\n        const blob = await ms.domToBlob(el, { ...opts, ...(bg ? { backgroundColor: bg } : {}) });\n        return { blob, paper: bg ? cssColorToRgb01(bg) : resolvePaperRgb(el) };\n      }\n      // Transparent up to the root. The visible backdrop may still come from an\n      // ancestor's background-image or a covering positioned layer (e.g. a hero\n      // art div) that the color walk can't see. Capture that ancestor and crop\n      // to the element so the real backdrop is embedded - correct for both the\n      // shader and the screenshot sent to the model. Fall back to white only\n      // when nothing is actually painted behind the element.\n      const backdrop = findBackdropAncestor(el);\n      if (!backdrop) {\n        const blob = await ms.domToBlob(el, { ...opts, backgroundColor: '#ffffff' });","sourceCodeStart":7958,"sourceCodeEnd":7994,"githubUrl":"https://github.com/pbakaus/impeccable/blob/f88b2837a7d7c3182e46307bbbb091a1ed547571/skill/scripts/live-browser.js#L7958-L7994","documentation":"When an element is captured via an ancestor-crop shader proxy, live-browser first renders the ancestor with modern-screenshot and crops out the element (inside hideCaptureChromeForShaderProxy). If that ancestor render throws — canvas size limits, tainted cross-origin content, renderer unsupported styles — the error is logged as 'ancestor crop capture failed, falling back to element capture:' and a direct capture of the element itself is used instead, so the generate flow continues.","triggerScenarios":"The proxy ancestor is enormous (viewport-sized hero at DPR 2 exceeding max canvas/texture size); ancestor contains cross-origin images or fonts that taint the canvas; modern-screenshot hits an unimplemented CSS feature inside the ancestor.","commonSituations":"Capturing an element inside a full-bleed hero with video/background-image art; very high pixel-ratio displays; pages pulling cross-origin assets without CORS headers.","solutions":["No action usually needed — the element-level fallback capture is taken automatically","If the fallback's background/paper looks wrong, capture from a plainer ancestor or fix cross-origin CORS headers on images/fonts","Reduce window scale (device pixel ratio cap is already 2) for gigantic ancestors"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"// Cap the ancestor render size before attempting crop capture\nconst MAX = 4096;\nconst scale = Math.min(window.devicePixelRatio || 1, 2, MAX / Math.max(ancestorRect.width, ancestorRect.height));","typeGuard":null,"tryCatchPattern":"try { return await captureElementFromRenderedAncestor(ms, el, opts); } catch (err) { console.warn(err); /* fall through to direct element capture */ }","preventionTips":["Serve images/fonts with CORS headers so the ancestor render is not tainted","Keep the shader-proxy ancestor reasonably sized; avoid viewport-wide proxies at DPR 2","Trust the built-in fallback: an element-level capture is always preferable to no capture"],"tags":["screenshot","modern-screenshot","canvas","fallback","svelte-preview"],"backgroundTag":"screenshot-capture-failed","analyzedSha":"f88b2837a7d7c3182e46307bbbb091a1ed547571","analyzedAt":"2026-08-18T04:58:36.608Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}