Users locked out?
Users can't sign in. It worked every time you tested it.
Sign-in is the one feature every user hits before anything else, and it is the feature AI builders test least. The tool wires up auth in minutes, you sign in once during the build, and it works. Then you move to a real domain and the parts you never exercised start failing: the confirmation email that points at the preview, the session that dies after an hour, the cookie the browser refuses to send. Broken auth is rarely mysterious. It is configuration that still describes the app you were building, not the one you shipped.
Fixed £4,500 · 3 days · pass-or-refund · next slot w/c 3 August
What actually breaks
- Redirect URLs still point at the preview domainYour auth provider resolves every confirmation email, magic link and OAuth callback against a configured site URL and an allowlist of redirect URLs. In Supabase, if the production domain is not on that list, there is no error: the redirect silently falls back to the site URL, which is whatever was set during the build, usually localhost or the preview domain. So a customer clicks a valid confirmation link and lands on a page that does not exist, and nothing in your logs says why.
- The default email sender is capped, and reset links bind to one browserSupabase's built-in email sender is, by its own docs, best effort and meant for development, rate limited to a few messages an hour. At launch, sign-ups blow past that cap and confirmation emails stop arriving. Password reset has a second trap: under the PKCE flow, which @supabase/ssr uses by default, the reset link only completes in the browser that requested it, because the code verifier lives there. A customer who requests a reset on a laptop and opens the email on a phone gets an error, not a new password.
- Session refresh signs users out instead of keeping them inAccess tokens are short lived, typically an hour. Staying signed in rests on refresh tokens, and in Supabase each one is single use: exchanging it revokes it. The docs allow a brief reuse window so a server and a browser sharing one session do not collide. A replay that lands outside that window, a stale token resent after a network stall, a client that never received its new token, is treated as token theft, and the entire session is revoked. The customer is dropped at the login screen mid task.
- The browser refuses the session cookie on your production domainThree attributes, three distinct failures. SameSite=Strict breaks the OAuth round trip: the hop back from Google is a cross-site navigation, so the browser withholds the state and PKCE cookies your app set before redirecting out, the callback fails its state check, and the user bounces between your app and the provider. SameSite=None without the Secure flag is discarded by modern browsers outright. And a Domain attribute pinned to www means visitors arriving on the bare domain never get the cookie, so some users can sign in and the rest cannot.
- The OAuth app is still in testing mode, registered to the wrong URIGoogle matches the redirect URI byte for byte: protocol, host, path, trailing slash. The URI registered during the build was the preview domain, so on your real domain every Google sign-in returns Error 400, redirect_uri_mismatch. Testing status is a separate snag: it caps the app at 100 listed test users, and if you request scopes beyond basic name, email and profile, each tester's authorisation, refresh tokens included, expires after seven days until you publish the app.
- Your emails send fine and land in the spam folderMoving off the capped default sender means your own SMTP provider and your own domain, and that brings a new gate: since February 2024 Gmail rejects or junks mail from senders with no SPF or DKIM authentication, and Outlook applies similar rules. Your email provider's dashboard will show these messages as delivered, because the receiving server accepted them; the spam folder counts as delivered. So the customer signs up, no email appears, and they are locked out before they start. The missing DNS records take minutes to add.
How I find where sign-in actually fails
Auth breaks in two places at once: the code in your repo and the configuration sitting in provider dashboards. So I test the way a stranger would. Fresh browser profile, new email address, your production URL. Sign up, wait for the email, click it, sign in, let the session expire, reset the password, run the Google round trip. Each failure is visible in the network tab: a redirect aimed at the wrong host, a Set-Cookie header the browser ignored, a 400 from Google naming the mismatched URI. Fixes go into your repository and into the dashboards together, Supabase URL allowlists, SMTP and DNS records, Google's registered URIs, because correcting one half leaves sign-in broken. Then the same flows run again, same clean profile, until they pass.
What “done” looks like
We agree one of these in writing before you pay anything. If it passes, the sprint passed. If it doesn't, you get a full refund and keep the work.
- A stranger with a new email address can sign up on the production domain, get the confirmation email in their inbox within a minute, and land signed in on your app, not on localhost or a preview URL.
- A password reset requested on one device completes on another: laptop requests it, phone opens the link, the new password works.
- A signed-in user whose access token has expired is refreshed silently, with two tabs open, and never lands back at the login screen.
- Confirmation and reset emails sent from your domain pass SPF and DKIM checks and reach the inbox, not spam, on both a Gmail and an Outlook test account.
We agree the acceptance test before any work starts. If it doesn't pass within three working days, you get a full refund and keep every change I've committed. The risk is mine, not yours.
Other things that block launches
- Your Lovable app works in the preview. It breaks in production.
- Stripe took the money. Your customer got nothing.
- Your Bolt.new app runs fine in the preview. The published version doesn't.
- Your Replit app works in the workspace. The published version doesn't.
- Your v0 app looks ready to ship. The part that breaks is the part you can't see.
- Your Base44 app works when you use it. It breaks when your customers do.
- Your Cursor app runs on your machine. That is the only place it has ever been tested.
- Your customers can see each other's data. It is never just the one screen you found.
- It runs on your laptop. It will not deploy anywhere else.
- Your AI feature is impressive when it works. You can't put it in front of a customer.
- The full The Launch-Blocker Sprint