{"record":{"id":"c955365fd32c915e","repo":"stablyai/orca","slug":"unable-to-determine-full-page-screenshot-bounds","errorCode":null,"errorMessage":"Unable to determine full-page screenshot bounds","messagePattern":"Unable to determine full-page screenshot bounds","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/main/browser/cdp-screenshot.ts","lineNumber":157,"sourceCode":"  }\n  const dbg = webContents.debugger\n  if (!dbg.isAttached()) {\n    throw new Error('Debugger not attached')\n  }\n\n  try {\n    webContents.invalidate()\n  } catch {\n    // Some guest teardown paths reject repaint requests. Fall through to CDP.\n  }\n\n  const metrics = await sendCommandWithTimeout<{\n    cssContentSize?: { width?: number; height?: number }\n    contentSize?: { width?: number; height?: number }\n  }>(webContents, 'Page.getLayoutMetrics', undefined, SCREENSHOT_TIMEOUT_MESSAGE)\n  const clip = getLayoutClip(metrics)\n  if (!clip) {\n    throw new Error('Unable to determine full-page screenshot bounds')\n  }\n\n  const { data } = await sendCommandWithTimeout<{ data: string }>(\n    webContents,\n    'Page.captureScreenshot',\n    {\n      format,\n      captureBeyondViewport: true,\n      clip\n    },\n    SCREENSHOT_TIMEOUT_MESSAGE\n  )\n\n  return { data, format }\n}\n\n// Why: Electron's capturePage() is unreliable on webview guests — the compositor\n// may not produce frames when the webview panel is inactive, unfocused, or in a","sourceCodeStart":139,"sourceCodeEnd":175,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/browser/cdp-screenshot.ts#L139-L175","documentation":"getLayoutClip() extracts content dimensions from Page.getLayoutMetrics to build the screenshot clip rectangle. If neither cssContentSize nor contentSize has valid finite positive width and height, it returns null and captureFullPageScreenshot() aborts. This is the same semantic as error 804 (in CdpBridge) but in the standalone module — it throws a plain Error without a BrowserError code. The cssContentSize preference avoids HiDPI device-pixel tiling on Retina displays.","triggerScenarios":"Screenshotting about:blank, a crashed renderer, or a page before its first paint/layout cycle; pages with zero-size content area (empty iframe, blank document).","commonSituations":"Internal pages (about:, chrome:); racing with navigation (screenshot before load); renderer crash; empty or display:none content.","solutions":["Ensure the page has loaded with visible, laid-out content before screenshotting.","Retry after waitForLoad or a short delay to allow layout to settle.","Avoid screenshotting about:blank, chrome://, or other internal pages with no content layout."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const url = webContents.getURL()\nif (!url || url.startsWith('about:') || url.startsWith('chrome:')) {\n  throw new Error('Cannot determine screenshot bounds for internal page — navigate to real content first')\n}\nconst result = await captureFullPageScreenshot(webContents, format)","typeGuard":null,"tryCatchPattern":"try {\n  return await captureFullPageScreenshot(wc, format)\n} catch (e) {\n  if (e instanceof Error && /bounds/.test(e.message)) {\n    // page has no layout; wait for load and retry, or navigate to real content\n    await new Promise(r => setTimeout(r, 500))\n    return await captureFullPageScreenshot(wc, format)\n  }\n  throw e\n}","preventionTips":["Ensure the page has loaded and laid out content before screenshotting.","Avoid screenshotting about:blank, chrome://, or pages with no visible content.","Retry after a short delay if the page is still computing its first layout."],"tags":["screenshot","layout","cdp","hidpi","no-bounds"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}