The patch panel (#6856) reads changes/changes.patch with fetch() against /api/runs/:runId/artifacts/*path, which 302s to a signed GCS URL.
The Sentry browser SDK adds sentry-trace and baggage to that fetch, since the URL is same-origin when the headers are decided. The browser then replays them across the redirect, so the cross-origin leg to GCS carries two non-safelisted headers and must be preflighted. GCS builds Access-Control-Allow-Headers from the bucket's CORS responseHeader list, so until those names were listed the preflight returned 200 with no
access-control-* headers and the read failed.
Unblocked for now by allowing OPTIONS in the bucket's CORS method list and adding sentry-trace and baggage to responseHeader. Worth revisiting:
- Every patch load costs an OPTIONS plus the GET, on top of our own 302. The preflight cache never helps because each load gets a freshly signed URL.
- GCS ignores
sentry-trace, so we send trace metadata to Google and get no trace continuity for it.
- Infra config now hardcodes SDK header names; a new propagation header would break the panel again as an opaque CORS error.
Possible fixes:
- Add an inline mode to the artifact route that proxies the preview bytes same-origin, keeping the 302 for download links. No CORS, no preflight, works locally, keeps browser-to-server trace linkage. Bytes transit Cloud Run, bounded by a read cap (I would avoid this solution).
- Exclude the artifact path from trace propagation:
tracePropagationTargets: [/^\/(?!api\/runs\/[^/]+\/artifacts\/)/]. Drops the preflight, but loses trace linkage for that route and still needs
bucket CORS for the GET.
The patch panel (#6856) reads
changes/changes.patchwithfetch()against/api/runs/:runId/artifacts/*path, which 302s to a signed GCS URL.The Sentry browser SDK adds
sentry-traceandbaggageto that fetch, since the URL is same-origin when the headers are decided. The browser then replays them across the redirect, so the cross-origin leg to GCS carries two non-safelisted headers and must be preflighted. GCS buildsAccess-Control-Allow-Headersfrom the bucket's CORSresponseHeaderlist, so until those names were listed the preflight returned 200 with noaccess-control-*headers and the read failed.Unblocked for now by allowing
OPTIONSin the bucket's CORSmethodlist and addingsentry-traceandbaggagetoresponseHeader. Worth revisiting:sentry-trace, so we send trace metadata to Google and get no trace continuity for it.Possible fixes:
tracePropagationTargets: [/^\/(?!api\/runs\/[^/]+\/artifacts\/)/]. Drops the preflight, but loses trace linkage for that route and still needsbucket CORS for the GET.