I spent a week rebuilding my personal site and most of the hard part wasn't writing code. It was figuring out which of my tools were telling me the truth.
Three times something reported success while doing nothing. Each one cost me at least an hour. Here they are.
The migration that applied nothing
I ran the migration. It printed this:
Then I opened the SQL editor and asked the database what tables it had.
Zero rows.
The command had exited clean because it did everything it was supposed to do except reach the database. I'd passed it a placeholder connection string. It parsed fine, failed to connect, and still exited zero.
I'd hit this before on Flotix. Migration files written to disk is not the same as migrations applied, and the exit code doesn't know the difference. The only thing that does is asking the database directly:
If that comes back empty, nothing happened. Doesn't matter what the terminal said.
The security policy that did nothing
My site stores photos in two paths. Originals stay private. Only the resized versions are supposed to be public.
I wrote a row level security policy to enforce that. Supabase accepted it. Right table, right roles, right operation:
Then I opened an original's URL in an incognito window and the image loaded.
The policy was fine. What I'd missed is that Supabase's public bucket route doesn't consult row level security at all. It serves from the bucket's public flag directly. My policy was being evaluated exactly zero times.
The fix was making the bucket private and serving renditions through my own route, which checks the path before fetching anything. The policy stayed as a second layer. But I only found any of this because I tested it from a browser instead of trusting that a saved policy meant a working policy.
The build that kept showing me deleted code
Twice I fixed something, checked, and saw the old broken version. Both times I assumed I'd fixed it wrong.
The first was my footer clock, stuck on a timezone eight hours off from mine. I changed the value. Still wrong. Changed it somewhere else. Still wrong. It took me five attempts to realize the working fix was sitting uncommitted on disk while I kept checking against a running dev server holding an old build.
The second was an import error pointing at line 5 of a file. I opened the file. Line 5 was something else entirely. The import had been deleted. The build cache hadn't noticed.
Both times the answer was the same:
Now when an error survives a fix, the first thing I check is whether the thing showing me the error is looking at the same code I am.
What these have in common
Every one of them is a report about work rather than the work itself. An exit code isn't a schema. A saved policy isn't a denied request. A dev server isn't your source files.
So I stopped accepting the report. Migration ran means query the database. Policy saved means request the URL in incognito. Fix applied means clear the cache first.
It's slower. It's also the difference between finding a problem in ten minutes and finding it in three hours.
