At 11:44pm I finally got the photo upload to tell me why it was failing. Thirteen minutes later I deleted the entire feature. Both of those commits are in yesterday's log, one after the other, and I think that pair says more about how I build than anything else I shipped all day.
Here is what was happening. Publishing a photo from the admin panel worked fine on my machine and crashed in production. Not a nice crash. Next replaces raw errors thrown from a server action with an opaque digest before it ever reaches the browser, so what I saw was a page that would not load and a random hash in the console. Upload failure, insert failure, an RLS policy quietly saying no -- all three looked exactly identical from the outside. I had no way to tell them apart.
So the fix was not really a fix. It was giving the thing a mouth. I stopped throwing from the action, returned the error through useActionState instead, and rendered it on the form. Now whatever Supabase actually said would show up on screen, in words, where I could read it.
The fix worked. The feature still did not.
And that is the part I did not expect. Once I could see the real message, I sat there looking at it and the question changed. It stopped being why is this broken and became why does this exist. The photo gallery was never on any roadmap. I built it because it looked easy on a slow afternoon. A lightbox. A like button. Heart confetti. A skeleton loader. A storage helper, a queries module, four test files.
I ran git rm. Twenty seven files. One thousand nine hundred and eighteen deletions against two insertions, and those two insertions were removing the Photos item from the admin nav and updating the test that asserted the route existed.
I left the database alone. The photos table and the storage bucket are still sitting there in Supabase, empty and harmless, outside this repo's reach. Chasing them down would have been another twenty minutes of work to save nothing.
What I took from it
- A silent error is far worse than a loud one. Make the thing talk before you decide anything about it.
- The same work that makes a feature debuggable also makes it painfully clear whether it deserves to be debugged.
- Anything that only exists because it was easy to build turns out to be just as easy to delete.
The rest of the day was members work. Gift memberships, a congratulations email, plan pricing moved to ₹149 a month and ₹1499 a year, and a genuinely annoying discovery that Razorpay plans are immutable, so repricing means recreating the plan rather than updating it. Real progress. But the commit I keep thinking about is the one where I ended a long day with less code than I started with.
Photos might come back one day. Honestly, probably not. Today I go finish the members flow instead.

