Skip to content

Windows desktop annotation screenshots are dropped because fetch(dataUrl) violates CSP #12265

Description

@vedprakash2302

Bug

In the Windows desktop app, selecting an element in the in-app browser, adding a comment, and attaching or sending the annotation drops the screenshot. T3 shows:

Could not capture the picked element
The annotation was kept without the screenshot.

The agent receives the comment, selector, HTML, and styles, but no image.

Version: 0.0.43-nightly.20260917.1851.

Reproduction

  1. Open a page in the desktop app's in-app browser. The affected page was Scout at http://localhost:3001/login.
  2. Select an element with the annotation picker and enter a comment.
  3. Attach the annotation or send it directly to an agent.
  4. Observe the missing image and the main app's DevTools error:
Connecting to 'data:image/png;base64,...' violates the following Content Security Policy directive:
"connect-src 'self' http: https: ws: wss:".
Fetch API cannot load data:image/png;base64,... .
Refused to connect because it violates the document's Content Security Policy.

This reproduces both on the Windows machine hosting the WSL backend and on a Surface connected to that backend through an SSH localhost forward. The tunnel is not required. Ordinary browser snapshots and DOM inspection work.

Cause confirmed in source

  • apps/desktop/src/preview/Manager.ts captures the crop with Electron and returns image.toDataURL().
  • apps/web/src/lib/previewAnnotation.ts calls fetch(annotation.screenshot.dataUrl) to create the attachment. That request is subject to connect-src.
  • apps/desktop/src/electron/ElectronProtocol.ts applies the policy above to both packaged client assets and the development proxy.
  • The conversion failure reaches the existing text-only fallback in PreviewView.tsx.

Proposed fix and verification

Reuse the existing dataUrlToFile helper to decode the generated base64 PNG directly, without a fetch. Keep CSP unchanged and preserve annotation text on missing or malformed screenshots, plus Electron's capture timeout and failure handling.

A local patch passed focused regression tests and an integrated Windows desktop check using the installed nightly's Electron shell with the patched development renderer at t3code-dev://app/, connected to an isolated WSL backend. The original desktop CSP remained enforced.

  • Attach then send delivered a 7,238-byte PNG of Scout's "Sign in" button. The image in OpenCode's native message event matched the composer file byte-for-byte.
  • Ctrl+Enter direct-send delivered an 11,202-byte PNG of "Continue with Google".
  • Both native provider messages contained image/png file parts, and the agent described the images correctly.
  • Neither flow produced the screenshot-failure toast or a CSP violation.

The patch has not been packaged into a new installer or retested on the Surface through SSH.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    acceptedfeature request acceptedbugSomething is broken or behaving incorrectly.via-triageFiled through npx t3 triage

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions