This week we fixed a bug in Brifora (an AI design studio for small businesses, built with Next.js and Supabase) that never threw a single error.
The symptom. In "My works", cross-stitch patterns showed up without a download link. Logos, pictures and videos were fine.
The cause. We store files in several Supabase Storage buckets, because each bucket has its own allowed MIME types and size limit: images in generations, videos in videos, PDF patterns in patterns. The history page signed every path in generations, with one exception for .mp4. A PDF path signed in the wrong bucket doesn't fail — createSignedUrl simply finds nothing and returns no URL. The UI then shows an empty slot, which looks exactly like "the file was never saved".
The fix. One shared function decides the bucket from the file extension, and every place that signs or deletes files uses it:
export function bucketForPath(path: string): StorageBucket { if (path.endsWith('.mp4')) return 'videos' if (path.endsWith('.pdf')) return 'patterns' return 'generations' } Then group the paths by bucket and sign each group in one batch call — one request per bucket, not one per file.
Lessons:
- If a rule ("which bucket?") lives in two files, it will drift. Put it in one place.
- Extension is a safe signal only if you set it when storing the file — not the provider.
- A missing URL should be visible in the UI as an error, not as an empty frame.
- Watch what the fix exposes: once PDFs had links, they would have landed in an
<img>tag. We added a separate "PDF" tile.
Brifora: https://brifora.app — built by Weblevo (weblevo.com).


