Bootstrap the is_admin() stub before anything references it - #166
Merged
Conversation
Preview branches have been failing since July with "function public.is_admin() does not exist", raised by the audit-log policy in 20260702000000. The function was defined straight in the production database and never entered this migration history, so a database built from these files alone does not have it. 20260720000000 already creates a deny-all stub, but that is three weeks too late to help. The stub moves to 20260613000001, the first migration that mentions is_admin() at all. That is deliberately not the first migration that breaks: a reference inside a function body resolves when the function runs, while a policy's USING expression resolves as the policy is created, so 20260613000001 applied cleanly and 20260702000000 was the one that failed. Guarding the earliest mention covers every later reference rather than only the first that happened to be a policy. The block in 20260720000000 stays — it is part of applied history, and it no-ops once the earlier one has run. Its comment is updated to say where the stub now comes from. Editing applied migrations is safe here: Supabase records them by version, so production will not re-run either file, and production's real is_admin() is untouched regardless — the guard creates the stub only when the function is absent. Verified on a fresh Postgres 17 with no is_admin() present, only the pieces Supabase itself provides (auth.uid, auth.users, profiles): all 15 migrations apply in order with no errors, where before the run died on 20260702000000. Re-applying both guard-bearing migrations over a real is_admin() that returns true leaves it returning true, so the stub cannot clobber production. Final state after the in-order replay is the intended one: anon holds no table or column INSERT on client_error_log, no INSERT policy remains, and record_client_error plus the quota table are present. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Contributor
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Updates to Preview Branch (fix/is-admin-bootstrap-order) ↗︎
Tasks are run on every commit but only new migration files are pushed.
❌ Branch Error • Sun, 16 Aug 2026 11:11:43 UTC View logs for this Workflow Run ↗︎. |
YurMil
added a commit
that referenced
this pull request
Aug 17, 2026
The Supabase check reports two different failures depending on where it runs, and the runbook only covered one of them. On a pull request it builds a database from the migration files and dies on public.profiles. On main it syncs to production and dies on "Remote migration versions not found in local migrations directory" — which it has been doing since at least 7 August, before any of the recent work. That second failure matters for task 1: nothing has synced to production for weeks, so db push is not going to apply the migration cleanly the way the document originally implied. Added the diagnosis, the migration list step, and the choice between capturing a remote-only version and discarding the record — with a warning against reaching for migration repair to silence the error, since that is how the drift got this far. Also frames the whole document around that drift: the repository and the production database disagree in both directions, and every task here is a symptom of it. Status table refreshed — #165 and #166 are merged, nanoid opened a new high alert today. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
YurMil
added a commit
that referenced
this pull request
Aug 17, 2026
Three things are pending that a checkout cannot do on its own, and one of them is time-sensitive: PR #164 is merged and deployed, so the production bundle already calls an Edge Function that does not exist yet. Error reports are being dropped, and the anon INSERT grant the PR exists to remove is still in place until the migration is applied. Also records the second half of the preview-check story. PR #166 fixes the is_admin() ordering; the check then fails on public.profiles, which is referenced by five migrations and defined by none. Closing that needs the real table definition dumped from production — reconstructing it from the columns the migrations happen to touch would turn the check green while describing a schema that does not exist. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
YurMil
added a commit
that referenced
this pull request
Aug 17, 2026
The Supabase check reports two different failures depending on where it runs, and the runbook only covered one of them. On a pull request it builds a database from the migration files and dies on public.profiles. On main it syncs to production and dies on "Remote migration versions not found in local migrations directory" — which it has been doing since at least 7 August, before any of the recent work. That second failure matters for task 1: nothing has synced to production for weeks, so db push is not going to apply the migration cleanly the way the document originally implied. Added the diagnosis, the migration list step, and the choice between capturing a remote-only version and discarding the record — with a warning against reaching for migration repair to silence the error, since that is how the drift got this far. Also frames the whole document around that drift: the repository and the production database disagree in both directions, and every task here is a symptom of it. Status table refreshed — #165 and #166 are merged, nanoid opened a new high alert today. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What was broken
The
Supabase Previewcheck has been failing since July with:is_admin()was defined straight in the production database and never entered this migration history, so a database built from these files alone does not have it.20260720000000already creates a deny-all stub — three weeks after the first migration that needs one.Because the check only runs when
supabase/changes, it fails on exactly the PRs where it matters and is silently skipped everywhere else. No migration has been validated by CI since 2 July, including the one merged in #164 an hour ago.The fix
The stub moves to
20260613000001, the first migration that mentionsis_admin()at all.That is deliberately not the first migration that breaks. A reference inside a function body resolves when the function runs; a policy's
USINGexpression resolves as the policy is created. So20260613000001applied cleanly and20260702000000was the one that died. Guarding the earliest mention covers every later reference instead of only the first one that happened to be a policy.The block in
20260720000000stays — it is part of applied history and no-ops once the earlier one has run. Only its comment changes, to say where the stub now comes from.Editing applied migrations is safe here. Supabase records them by version, so production re-runs neither file; and production's real
is_admin()is untouched in any case, because the guard creates the stub only when the function is absent.Verification
On a fresh Postgres 17 with no
is_admin()present, scaffolded with only what Supabase itself provides (auth.users,auth.uid(),public.profiles):20260702000000;is_admin()that returnstrueleaves it returningtrue, so the stub cannot clobber production;Final state after the in-order replay is the intended one:
client_error_logauthenticated: SELECTonlyclient_error_logrecord_client_errorpresentclient_error_report_quotapresentFollow-up worth considering
The scaffolding above —
auth.uid(),auth.users,profiles— is what a from-scratch database still cannot produce on its own.profilesin particular is referenced by20260702000003and defined nowhere in this history, so the same class of failure is one policy away from returning. Bringing those into the migration history would make the preview check trustworthy rather than merely passing.🤖 Generated with Claude Code