Building with AI, in public
What I’m learning and building with AI, written in the open. Names and proprietary detail stripped out. Just the lessons.
- Why Content Fingerprinting Beat My Subject-Hash Dedup (By a Mile)
- The Memory Cap That Was Crying Wolf
- What CSP Taught Me About Third-Party Resource Types
- The Three Lines That Fixed a Race Condition I Didn't Know I Had
- How an Unrelated Migration Broke Our PostgREST Queries — One of Them Silently
- How CSS GPU Layers Broke My Drag-and-Drop Board (And the Fix Was Removing Code)
- How I Hardened Apollo's Scanner Against Prompt Injection (Two Cheap Fixes That Actually Work)
- How My Own Robot Reviewer Caught My Secret Sitting in `ps aux`
- How One Bad Enum Was Silently Killing My Entire Scan Batch
- How Playwright Became the Net That Let Me Actually Fix the Board
- How SWR's Default Refetch Behavior Was Trashing My Drag-and-Drop Board
- The One-Liner My Autonomous Council Flagged That I'd Never Have Caught
- The One Retry Rule I Wish I'd Learned Before Building Two Systems
- The Problem With Letting Your AI Agents Read Their Own Prior Work
- Validate Your Env Vars at Boot — or Pay the Price Later
- What Pydantic's `extra="forbid"` Gets Wrong When Your Data Comes From an LLM
- Why dnd-kit's Default Collision Detection Kept Picking the Wrong Target
- Why I Ended Up with One JSON Parser for Two Different LLM Models
- Why My Custom Tailwind Class Kept Losing (And the One-Word Fix That Saved It)
- My Own Rule Said Don't Cap It. I Capped It Anyway.
- SQL Injection Was Hiding in My Supabase `.not('in')` Calls
- The Bug That Corrupted My Scanner State (And the Three-Line Fix)
- The One-Liner That *Looked* Safe (and How an Origin Check Fixed It)
- How a Single String Was Gutting My Entire Content Security Policy
- The Save Worked. The UI Still Snapped Back. Here's Why.
- When Your MCP Search Returns the Envelope, Not the Data
- The Lazy Loading Trap That Made My LCP Worse (And How I Fixed It)
- The Shopify Sync That Never Had a Race Condition (And the Ones That Did)
- When the Swift Compiler Refuses to Build Your View, Listen to It
- Why Stripping HTML Tags Isn't Enough: Two CMSes Taught Me This in One Week
- Stop Saving on Return. Mobile Users Tap Away.
- The Auth Gate That Wasn't Guarding the Real Door
- Why Every Create Flow Should Auto-Navigate to What You Just Made
- Why Swipe-to-Delete Always Needs a Confirmation Step
- An ID Is Not a Password: How We Closed an IDOR in Our Cancer Patient Chat App
- How a Fullscreen Overlay Fixed Our Broken Mobile Booking Form
- How Eliminating `any` Types Made Our Build the First Line of Defence
- How localStorage Bridged Sessions — And Then Became a Security Hole
- How Two Characters Broke My HubSpot Pre-Fill (and What It Taught Me About Third-Party Forms)
- When Your Validator Is the Bug, Not the Data
- How a Failed Junction Insert Left Me With Orphaned Rows
- How an Open Redirect Hid Inside Our Next.js Server Actions
- Page Auth Doesn't Guard Server Actions — Every Action Needs Its Own Lock
- The API Won't Tell You When You're Paying Twice
- The Supabase Linter Warning That Silently Empties Your Tables
- Why I Stopped Letting Chat Failures Eat My Users' Words
- Why I Stopped Trusting My Own Frontend
- A Generator Script in Your Repo Is Not Proof It Made Your Assets
- How Prisma's Nested Relation Creates Silently Ate My Sales Data
- How Targeted Diagnostics Killed a Timezone Bug I'd Been Guessing At
- One Missing Env Var That Took Down Every Cron Job at Once
- The AI Recommendations Looked Great. The Data Was Lying.
- The Metric Was Wrong Because the Baseline Was Wrong
- The Timezone Bug That Taught Me to Measure From What You Trust
- When Your Data Is Saving Fine and the Dashboard Still Lies to You
- Why My GA4 Dashboard Worked Locally but Broke on Vercel Every Time
- How "Belt-and-Suspenders" Broke My Swift Supabase Decoder
- How My iOS App Learned to Lie (And How I Fixed It)
- How One `await` Stopped My iOS CRM From Lying to Users
- The SupabaseClientOptions Argument Order Trap Nobody Warns You About
- Why My Supabase iOS App Failed Silently — and It Was the Key Format
- Why Your Demo Mode Should Touch Zero Backend
- What "Replaced Element" Actually Means (and Why It Broke My Presentation Mode Canvas)
- How a Swapped Argument Order Killed Our Supabase iOS Connection (Silently)
- How Supabase's Batch Upsert Silently Swallowed Our Sales Data
- Why I Built a Demo Mode That Never Touches the Backend