{"record":{"id":"3314392a74170847","repo":"pbakaus/impeccable","slug":"selected-element-has-no-visible-capture-rect","errorCode":null,"errorMessage":"Selected element has no visible capture rect","messagePattern":"Selected element has no visible capture rect","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"skill/scripts/live-browser.js","lineNumber":8148,"sourceCode":"\n  // Capture the element (with current annotations baked in) and return\n  // { blob, paper }: the PNG Blob, plus the representative backdrop tone for the\n  // shader's halftone ground (so capture, upload, and shader all agree on what\n  // sits behind the element). Shared between the Go flow (uploads the blob) and\n  // the shader-resume path.\n  async function captureElementFromRenderedAncestor(ms, el, opts) {\n    const doc = el.ownerDocument || document;\n    const captureRoot = findShaderProxyCaptureRoot(el);\n    if (!captureRoot) throw new Error('No painted ancestor for Svelte shader proxy');\n    const rootCanvas = await ms.domToCanvas(captureRoot, opts);\n    const S = opts.scale;\n    const er = el.getBoundingClientRect();\n    const rr = captureRoot.getBoundingClientRect();\n    const sx = (er.left - rr.left) * S;\n    const sy = (er.top - rr.top) * S;\n    const sw = er.width * S;\n    const sh = er.height * S;\n    if (sw <= 0 || sh <= 0) throw new Error('Selected element has no visible capture rect');\n    const crop = doc.createElement('canvas');\n    crop.width = Math.max(1, Math.round(sw));\n    crop.height = Math.max(1, Math.round(sh));\n    const cctx = crop.getContext('2d', { willReadFrequently: true });\n    cctx.drawImage(rootCanvas, sx, sy, sw, sh, 0, 0, crop.width, crop.height);\n    const paper = dominantRgb01(cctx, crop.width, crop.height) || averageRgb01(cctx, crop.width, crop.height);\n    const blob = await new Promise((res) => crop.toBlob(res, 'image/png'));\n    if (!blob) throw new Error('Ancestor crop failed to produce a PNG blob');\n    return { blob, paper };\n  }\n\n  async function captureElementToBlob(el, snapshot, rect) {\n    try { if (document.fonts?.ready) await document.fonts.ready; } catch {}\n    const hasAnnotations = snapshot && (snapshot.comments.length > 0 || snapshot.strokes.length > 0);\n    let annotNode = null;\n    let savedPosition = null;\n    if (hasAnnotations) {\n      const pos = getComputedStyle(el).position;","sourceCodeStart":8130,"sourceCodeEnd":8166,"githubUrl":"https://github.com/pbakaus/impeccable/blob/2bc2879276c1f321a53c4ca99d3371e411329b52/skill/scripts/live-browser.js#L8130-L8166","documentation":"After computing the element's rect relative to the captured ancestor canvas, this is thrown when the scaled crop width or height is <= 0 — i.e. the selected element has no visible box to crop from the rendered canvas. The capture pipeline refuses to produce a zero-area canvas.","triggerScenarios":"el.getBoundingClientRect() returns zero width/height because the element is display:none, not rendered, detached from the document, or collapsed (e.g. empty flex item with no size).","commonSituations":"Selecting an element in DevTools-like UI while it is hidden behind a toggle; targeting a slot/placeholder with no rendered content; capture triggered before first paint after route change.","solutions":["Verify the element is visible and has non-zero bounding box before triggering capture (check getBoundingClientRect yourself)","Re-select the actual visible element rather than a hidden wrapper","Ensure any collapse/animation has finished and the element is painted before capturing","If capturing programmatically, force layout/visibility (or skip the effect) when rect is empty"],"exampleFix":"// before\nconst crop = captureElementFromRenderedAncestor(ms, el, opts); // throws deep inside\n// after\nconst r = el.getBoundingClientRect();\nif (r.width <= 0 || r.height <= 0) throw new Error('Element is not visible; nothing to capture');\nconst crop = captureElementFromRenderedAncestor(ms, el, opts);","handlingStrategy":"validation","validationCode":"const r = el.getBoundingClientRect();\nif (r.width <= 0 || r.height <= 0) {\n  throw new Error('Element has no visible capture rect');\n}","typeGuard":"function hasVisibleRect(el) {\n  const r = el.getBoundingClientRect();\n  return r.width > 0 && r.height > 0;\n}","tryCatchPattern":"try {\n  await captureElementToBlob(el, snapshot, rect);\n} catch (err) {\n  if (err.message.includes('no visible capture rect')) {\n    showToast('Selected element is not visible; make it visible before applying the effect.');\n  }\n}","preventionTips":["Check getBoundingClientRect().width/height > 0 before capturing","Ensure animations/collapse transitions have finished and the element is painted","Re-select a visible element instead of hidden wrappers or empty slots","Avoid triggering captures while the element is detached or display:none"],"tags":["canvas","capture","dom","visibility"],"backgroundTag":"zero-size-element","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"}