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  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-screenshotson the Cloudflare account - CDN URL:
https://bugs.casaconomy.app/<UUID>.png - Auth pattern: daemon reads
CASACONOMY_R2_BEARER_TOKENfrom env; PUT toCASACONOMY_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.pngextension — no user-data in the filename - Frontend change:
useReportIssueStoresendsUint8Arrayvia Tauri’sinvokeinstead 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.