- Shipped
- August 7, 2026 at 7:51 AM UTC
- Author
- kamo
- Commit
- 271b7e3
The org branding screen **************** showed the full and simple logos as missing images even though the very same files render fine everywhere else in the app. safeImageSrc() rewrites a foreign URL to /api/images/proxy?src=..., and Next refuses to optimize a local src that carries a query string: images.localPatterns defaults to [{ pathname: '**', search: '' }], so /_next/image answers 400 "url" parameter is not allowed. Confirmed against prod -- /_next/image?url=/logo/logo.svg 200, the same path with any query 400. A blob: preview of a just-picked file fails the same check on its absolute-URL branch, so the previews were broken before AND after upload. Behind that sits a second failure the 400 was hiding: the optimizer fetches a local src through a mocked request built with no headers at all, so the session cookie never reaches the proxy and it answers 401. So these images must not reach the optimizer. Adds app/components/SafeImage.tsx -- next/image with safeImageSrc applied and unoptimized set, which puts the proxy request back in the browser where the cookie is -- and moves every call site onto it: the six logo previews here plus the email template preview, the email image block, the Meet branding tab and the dashboard post avatar, all broken the same way since the safeImageSrc sweep. Plain <img> sites are untouched; they never hit the optimizer, which is why the theme backgrounds on this same screen kept working. scripts/check-safe-image.mjs keeps it from coming back -- the convention alone already failed once.