Thanks to the vercel AI checklist — I went through all four points against our actual code before replying, so this isn't guesswork:
1. import 'server-only' at the top of the admin-client file — already present (line 1 of src/lib/supabase/admin.ts), before this ticket was opened.
2. Instantiate inside function scope, not module top-level — process.env.SUPABASE_SERVICE_ROLE_KEY is read inside createAdminClient()'s function body, and that function is only ever called from inside the inviteMember Server Action handler. Nothing touches process.env at module top-level.
3. Avoid destructuring process.env — the code uses direct static property access: const key = process.env.SUPABASE_SERVICE_ROLE_KEY;. No destructuring, no dynamic process.env[key] lookup.
4. Trigger a clean rebuild and redeployment — already done twice independently: once via a genuine git-triggered PR merge build (dpl_GekHi3xqBg49rbpqqZqA3i4QCLWN), and once via a completely separate CLI-triggered build a few minutes later. The error recurred on the git-triggered build itself — at 2026-08-14T19:50:39Z, minutes after that fresh deployment went live and was serving traffic — so it isn't stale-build state.
So all four recommendations were either already true of our code, or already tried, before this symptom occurred. None of them explain the failure we're seeing.
To restate the specific, reproducible pattern that doesn't fit the "module boundary / bundler inlining" theory: within a single request/invocation of the inviteMember Server Action, an earlier call to a different function (createClient() in src/lib/supabase/server.ts) successfully reads process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY — the code only reaches createAdminClient() afterward, once that first Supabase query has already succeeded. Then, moments later in that same invocation, createAdminClient() reads process.env.SUPABASE_SERVICE_ROLE_KEY as empty. If this were a module-evaluation/bundling issue, I'd expect it to affect env var reads consistently within a request, not have one env var read succeed and a different one fail moments later in the same function execution.
One more data point: this only happens in production. Running the exact same code locally (npm run dev, same .env values pointing at the same Supabase project) never reproduces it — createAdminClient() reads SUPABASE_SERVICE_ROLE_KEY successfully every time locally. That rules out anything in our code, bundler config, or the server-only boundary itself, since it's the identical build output running against the identical env var value. This narrows it specifically to something in how Vercel's production runtime delivers that one var to that one function.
Could someone look directly at the build output and function logs for project advisory-assessment (prj_V4eLPZh9iI7Km3ltppmPiNgyCeVE, team STRAVIB) around deployment dpl_GekHi3xqBg49rbpqqZqA3i4QCLWN and the specific invocation at 2026-08-14T19:50:39Z, rather than the general checklist? Happy to provide anything else needed — request IDs, additional log windows, etc.
admin: https://vercel.com/stravib1/advisory-assessment/69S34FviWhFPJma5dSV2AQ2nRVCE