fix(screenshot): fall back to CDP capture when captureVisibleTab fails - #83
Merged
Conversation
chrome.tabs.captureVisibleTab reads back the window surface, which fails outright on some Windows/Chrome combinations (Chromium FAILURE_REASON_READBACK_FAILED: "Failed to capture tab: image readback failed"), leaving full-tab screenshots without any working path. Capture the full tab via CDP Page.captureScreenshot (fromSurface) when the visible-tab capture rejects; the CDP path goes through the renderer BeginFrame pipeline instead of the surface readback. When both paths fail, return cdp_failed with data.reason=screenshot_capture_failed carrying both underlying messages, and render a CLI hint that points at the browser-side readback cause. Refs #71
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
Refs #71 — on some Windows + Chrome 151 setups,
bsk screenshotalways fails withFailed to capture tab: image readback failed. That error string is produced inside Chromium (FAILURE_REASON_READBACK_FAILEDinchrome/browser/extensions/api/tabs/tabs_api.cc): the browser's compositor fails to read the window surface back into a bitmap, sochrome.tabs.captureVisibleTabrejects and no image data ever reaches the extension. The full-tab screenshot path had no fallback, so a browser-side readback failure surfaced as a hard error.Changes
apps/extension/src/tools/observation.ts): full-tab capture now falls back to CDPPage.captureScreenshot(format: "png",fromSurface: true) whencaptureVisibleTabrejects. The CDP path captures through the renderer's BeginFrame pipeline instead of the window-surface readback thatcaptureVisibleTabdepends on. Overlay suppression (withOverlaysHiddenForCapture) wraps both attempts, and the CDP session is attached the same way the existing--refelement-capture path does it. When both paths fail, the error carriesdata.reason = "screenshot_capture_failed"and both underlying messages.crates/bsk-cli/src/cli/render_error.rs): newscreenshot_capture_failedreason override forcdp_failedwith a hint that points at the browser-side rendering/readback cause (reload tab / restart browser / upgrade or downgrade Chrome) instead of the generic "stuck DevTools session" copy.Page.captureScreenshotparams, (2) both paths fail →cdp_failed+screenshot_capture_failedreason + both messages, (3) primary success never touches CDP; a Rust unit test locking the new reason-override copy.Notes / honesty
The underlying readback regression is inside the browser, so this PR is a mitigation: it routes around the broken capture path rather than fixing it. The exact Chromium 151 change that breaks surface readback on the reporter's machine still needs verification on a real Windows environment.
Test plan
pnpm --filter @browser-skill/extension compilepnpm ext:test(618 passed)pnpm lintcargo fmt --all -- --check,cargo clippy --workspace --all-targets --locked -- -D warnings,cargo test --workspace --locked