[GH-ISSUE #2595] fix(browser): malformed screenshot responses report a size-limit error #911

Closed
opened 2026-10-15 18:29:30 +00:00 by bsakaguchi · 1 comment
Owner

Originally created by @coygeek on GitHub (Oct 13, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/2595

Summary

Capturing a screenshot from an approved page reports a size-limit failure when the protocol response has no image data or invalid base64. Callers receive the same machine-readable classification used for bounded truncation, so they cannot distinguish unusable producer output from an actual size limit.

Runtime or environment

Source revision 8b181716ac, Node v26.10.0, npm 11.19.1, and locked dependencies. Verification used an in-memory CDP connection and did not launch Chrome.

Steps to reproduce

  1. In a focused Vitest test beside CdpScreenshot.ts, invoke captureCdpScreenshot with a mocked connection. Make Page.getFrameTree return frameTree.frame with id main and url https://app.example.test/ for both reads, make onEvent return a removal callback without sending any events, and return empty objects for setup commands.
  2. Supply sessionId undefined, target id page with type page and the same approved URL, allowed_origins ["https://app.example.test"], target_id page, and cdp_endpoint http://127.0.0.1:9222. Supply a discovery version object with product Chrome/1, protocol_version 1.3, revision 1, user_agent ua, and js_version 1.
  3. Independently test Page.captureScreenshot returning {}, {"data":""}, and {"data":"not-base64!!!"}. Catch each thrown error and inspect its reason and projectAnalysisError output.
  4. Run npm run test:focused -- src/browser/screenshot-result.test.ts for the created test. Expect protocol_error and projected code unreadable_output for each case.

Expected behavior

Missing or malformed screenshot data is an unusable protocol result. It must have the same protocol-failure classification as malformed PNG data, rather than claiming that an image exceeded a resource limit.

Actual behavior

All three executed cases threw reason payload_limit. Their error projections had code truncated and category truncated. No screenshot was returned. The decoder rejects these values for encoding validity, without applying a size bound.

Evidence

  • Expected source: AGENTS.md, Architecture and Cleanup, requires meaningful failure reasons; src/browser/CdpScreenshot.ts:98-100 uses protocol_error for unusable PNG data; src/domain/analysisErrorProjection.ts:130-147 distinguishes size-limit and protocol classifications.
  • Failure source: src/browser/CdpScreenshot.ts:93-97 throws payload_limit for missing data or decoder rejection; src/domain/webScreenshot.ts:155-160 validates canonical encoding without a size constraint; src/browser/CdpBrowserProvider.ts:449-461 preserves the reason on public propagation.
  • Evidence provenance: observed
  • Local verification: reproduced
  • Reproduction completeness: complete

Each case used the same authorized frame before and after capture, passed setup, and emitted no navigation events. Parameterized tests established all three failures independently. The tests establish handling of malformed producer data, not that Chrome commonly returns such data. No matching issue was found in read-only searches.

Restoration check

Repeat each malformed response and require protocol_error with projected code unreadable_output. A canonical encoding of invalid PNG bytes must remain a protocol failure, a valid PNG capture must remain successful, and actual transport size-limit failures must retain their separate truncation classification.

Triage assessment

  • Impact level: P2
  • Assessment status: supported
  • Impact basis: A bounded failure path returns an incorrect machine-readable code and category, preventing callers from distinguishing malformed output from resource truncation. The screenshot still fails, and no image data is silently accepted.
  • Workaround status: unverified
  • Workaround basis: No tested caller-visible diagnostic distinguishes this case from a real size limit. Retrying a different target was not verified to correct malformed protocol data.
Originally created by @coygeek on GitHub (Oct 13, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/2595 ## Summary Capturing a screenshot from an approved page reports a size-limit failure when the protocol response has no image data or invalid base64. Callers receive the same machine-readable classification used for bounded truncation, so they cannot distinguish unusable producer output from an actual size limit. ## Runtime or environment Source revision 8b181716aca2cb467be499cba226abfb5ae19141, Node v26.10.0, npm 11.19.1, and locked dependencies. Verification used an in-memory CDP connection and did not launch Chrome. ## Steps to reproduce 1. In a focused Vitest test beside CdpScreenshot.ts, invoke captureCdpScreenshot with a mocked connection. Make Page.getFrameTree return frameTree.frame with id main and url https://app.example.test/ for both reads, make onEvent return a removal callback without sending any events, and return empty objects for setup commands. 2. Supply sessionId undefined, target id page with type page and the same approved URL, allowed_origins ["https://app.example.test"], target_id page, and cdp_endpoint http://127.0.0.1:9222. Supply a discovery version object with product Chrome/1, protocol_version 1.3, revision 1, user_agent ua, and js_version 1. 3. Independently test Page.captureScreenshot returning {}, {"data":""}, and {"data":"not-base64!!!"}. Catch each thrown error and inspect its reason and projectAnalysisError output. 4. Run npm run test:focused -- src/browser/screenshot-result.test.ts for the created test. Expect protocol_error and projected code unreadable_output for each case. ## Expected behavior Missing or malformed screenshot data is an unusable protocol result. It must have the same protocol-failure classification as malformed PNG data, rather than claiming that an image exceeded a resource limit. ## Actual behavior All three executed cases threw reason payload_limit. Their error projections had code truncated and category truncated. No screenshot was returned. The decoder rejects these values for encoding validity, without applying a size bound. ## Evidence - Expected source: AGENTS.md, Architecture and Cleanup, requires meaningful failure reasons; src/browser/CdpScreenshot.ts:98-100 uses protocol_error for unusable PNG data; src/domain/analysisErrorProjection.ts:130-147 distinguishes size-limit and protocol classifications. - Failure source: src/browser/CdpScreenshot.ts:93-97 throws payload_limit for missing data or decoder rejection; src/domain/webScreenshot.ts:155-160 validates canonical encoding without a size constraint; src/browser/CdpBrowserProvider.ts:449-461 preserves the reason on public propagation. - Evidence provenance: observed - Local verification: reproduced - Reproduction completeness: complete Each case used the same authorized frame before and after capture, passed setup, and emitted no navigation events. Parameterized tests established all three failures independently. The tests establish handling of malformed producer data, not that Chrome commonly returns such data. No matching issue was found in read-only searches. ## Restoration check Repeat each malformed response and require protocol_error with projected code unreadable_output. A canonical encoding of invalid PNG bytes must remain a protocol failure, a valid PNG capture must remain successful, and actual transport size-limit failures must retain their separate truncation classification. ## Triage assessment - Impact level: P2 - Assessment status: supported - Impact basis: A bounded failure path returns an incorrect machine-readable code and category, preventing callers from distinguishing malformed output from resource truncation. The screenshot still fails, and no image data is silently accepted. - Workaround status: unverified - Workaround basis: No tested caller-visible diagnostic distinguishes this case from a real size limit. Retrying a different target was not verified to correct malformed protocol data.
bsakaguchi 2026-10-15 18:29:30 +00:00
Author
Owner

@morluto commented on GitHub (Oct 14, 2026):

Addressed on main in bffdd91053fb5d076b762cf1b325e8dcb5ab2d8c.

Malformed screenshot base64 is reported as a protocol error rather than a size limit.

Validation: Affected suites passed in the merged 65-file run (1169 passed, 2 explicit skips), with full static/architecture checks and documentation checks passing. Final installed-package verification is recorded separately in the audit.

Verification scope: Controlled source and production-boundary verification on macOS with pinned Node 24.18.0; real external engines and Windows hosts were not independently rerun. Closure covers the described source defect, not broader provider conformance or performance.

<!-- gh-comment-id:6159211253 --> @morluto commented on GitHub (Oct 14, 2026): Addressed on main in [bffdd91053fb5d076b762cf1b325e8dcb5ab2d8c](https://github.com/morluto/rea/commit/bffdd91053fb5d076b762cf1b325e8dcb5ab2d8c). Malformed screenshot base64 is reported as a protocol error rather than a size limit. Validation: Affected suites passed in the merged 65-file run (1169 passed, 2 explicit skips), with full static/architecture checks and documentation checks passing. Final installed-package verification is recorded separately in the audit. Verification scope: Controlled source and production-boundary verification on macOS with pinned Node 24.18.0; real external engines and Windows hosts were not independently rerun. Closure covers the described source defect, not broader provider conformance or performance.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#911
No description provided.