Skip to content

Bug-report screenshots hosted on Cloudflare R2

Bug-report screenshots hosted on Cloudflare R2

Status: Delivered
CAS: CAS-2848
Delivered: 2026-05-14
PRs: #770

What’s new

Bug-report screenshots are now uploaded to a private Cloudflare R2 bucket (casaconomy-bug-screenshots) rather than a GitHub Gist. Screenshots appear as properly rendered images in GitHub issue comments and in the Astrid chat thread.

What changed

Before: The daemon uploaded screenshots as base64-encoded text content to a GitHub Gist. GitHub unconditionally serves Gist raw URLs as text/plain, so ![screenshot](url) in the GitHub issue body rendered as a broken image. The UI sent screenshot data as a base64 string inside the JSON payload.

After: The frontend converts the canvas blob to a Uint8Array before sending. The daemon PUTs the raw bytes directly to R2 via a bearer-token-authenticated request and returns the public CDN URL. The issue comment and chat bubble both embed the live CDN URL as a proper image.

Implementation details

  • R2 bucket: casaconomy-bug-screenshots on the Cloudflare account
  • CDN URL: https://bugs.casaconomy.app/<UUID>.png
  • Auth pattern: daemon reads CASACONOMY_R2_BEARER_TOKEN from env; PUT to CASACONOMY_R2_UPLOAD_URL; no public-read ACL required — the CDN URL is the only public surface
  • Filename: random UUID per screenshot (uuid::Uuid::new_v4().to_string()) with .png extension — no user-data in the filename
  • Frontend change: useReportIssueStore sends Uint8Array via Tauri’s invoke instead of a base64 string; receiving command type-annotated accordingly

Why we built it

GitHub Gist raw URLs respond with Content-Type: text/plain regardless of file extension. Every bug report screenshot was arriving as a broken image link. Moving to R2 gives proper image serving, no GitHub API coupling, and full control over retention and access policy. UUID filenames decouple the object key from any user-visible information.