ticField Manual — Vibe-Code RescueAPPENDIX A / FIELD GUIDE
← Back to intake

Appendix A — Field Guide

The 11 things that break AI-built apps.

Every Lovable / Bolt / Supabase build fails in roughly the same eleven ways before it can launch. Here's each one — the symptom, the real cause, and the first thing to check. Keep it open the next time something breaks; when it's deeper than a checklist, that's what the free diagnosis is for.

Auth & session

01 getUser() returns null on the server

Likely cause. Your server Supabase client isn't reading the auth cookies, so RLS treats the request as anonymous.

First check. Confirm you use createServerClient wired to cookies(), call getUser() on the server, and add middleware to refresh the session.

02 "Auth session missing" / user is null on the client

Likely cause. No single shared browser client, or the component reads the session before it hydrates.

First check. Create one shared createBrowserClient and gate auth-dependent reads until the first session resolves.

03 Login works locally but breaks after deploy

Likely cause. Production config gaps — not your code.

First check. Add your prod URL + /auth/callback to Supabase → Authentication → URL Configuration, and set the env vars on the host. 90% of these are the redirect-URL list.

04 OAuth/PKCE: "both auth code and code verifier should be non-empty"

Likely cause. The callback isn't a server route sharing the same cookie store that held the PKCE verifier.

First check. Handle the callback server-side and call exchangeCodeForSession(code) with the same cookie adapter as sign-in.

05 "Email not confirmed" — users can't log in

Likely cause. Supabase “Confirm email” is on, so users must click the link before signing in.

First check. Either turn off Confirm email for a frictionless flow, or handle the “check your email” state + correct redirect URL.

Database & RLS

06 "new row violates row-level security policy" (42501)

Likely cause. The insert runs without an auth context that satisfies the policy.

First check. Insert with the user id and add a matching policy: for insert to authenticated with check (auth.uid() = user_id).

07 "infinite recursion detected in policy" (42P17)

Likely cause. A policy queries the same table it protects (classic with profiles/roles).

First check. Move the lookup into a SECURITY DEFINER function (it bypasses RLS, breaking the loop), or check auth.uid() = id directly.

Stripe

08 Payment went through but the app never marks the user subscribed

Likely cause. The webhook isn't verified/handled — usually the route parses the body before the signature check.

First check. Verify with the raw body + STRIPE_WEBHOOK_SECRET, handle checkout.session.completed, then upsert the subscription.

Deploy, build & env

09 "Invalid API key" / Supabase 403

Likely cause. Wrong or missing env — project mismatch, service_role used in the browser, or NEXT_PUBLIC not rebuilt.

First check. Confirm NEXT_PUBLIC_SUPABASE_URL + ANON_KEY match the right project, never ship service_role to the browser, and redeploy (NEXT_PUBLIC is inlined at build).

10 Build fails on a TypeScript union/enum error

Likely cause. AI-generated code feeds a raw string (often from FormData) into a narrow typed field.

First check. Narrow at the boundary with a small parser + safe default — don't `as`-cast it (that hides the bug until runtime).

11 Works locally, build fails on Vercel

Likely cause. Env vars not set for Production, or a real build error that only surfaces in CI.

First check. Read the Vercel build log for the exact line, add the env vars to Production + redeploy, reproduce with npm run build locally.

Stuck past the checklist?

Paste your exact error into the free diagnosis. If it needs hands-on work, one scoped blocker is $90 — paid only after it works.