
How We Made Our Supabase RLS Migrations Idempotent (And Why You Should Too)
The Problem You write a Supabase migration, it runs fine locally. You push to staging — fine. Then you need to re-apply it (rollback test, fresh CI environment, or a teammate cloning the repo) and suddenly: ERROR: policy "Users can view own stitched exports" for table "stitched_exports" already exists PostgreSQL's CREATE POLICY (and CREATE INDEX ) doesn't have an IF NOT EXISTS guard. So if your migration runs twice, it blows up. This hit us in ClipCrafter when working on a new stitched_exports table. Here's the before: CREATE INDEX stitched_exports_project_id_idx ON stitched_exports ( project_id ); ALTER TABLE stitched_exports ENABLE ROW LEVEL SECURITY ; CREATE POLICY "Users can view own stitched exports" ON stitched_exports FOR SELECT USING ( EXISTS ( SELECT 1 FROM projects WHERE projects . id = stitched_exports . project_id AND projects . user_id = auth . uid () ) ); CREATE POLICY "Service role full access to stitched_exports" ON stitched_exports FOR ALL USING ( auth . role () = 'ser
Continue reading on Dev.to
Opens in a new tab



