Guides · 3 min
Troubleshooting
The failures that look like something else, and the one line that fixes each.
The magic link signs me out immediately
The Supabase email templates are still the defaults, which return the session
in a URL fragment your server never sees. Rewrite all three to use
?token_hash={{ .TokenHash }}. See Authentication.
I sign in, then I am signed out on the next page
proxy.ts is not running, or it is not matching the route. Server Components
cannot write cookies, so without it nothing refreshes the session. Check the
matcher at the bottom of the file.
If it only happens on the callback, the client there is bound to
next/headers rather than to the response. That mutation does not survive a
redirect.
Checkout returns 503
STRIPE_SECRET_KEY is missing. That is deliberate: the app runs without Stripe
so you can build before you bill.
"Expired API Key provided"
You activated live mode, which invalidates the existing test keys. Copy the new test keys from the dashboard.
The payment worked but nothing happened
Look at the Stripe dashboard's event log, not yours. It shows the response your webhook returned.
- 400: signature mismatch. The secret in your environment belongs to a different endpoint.
- 503:
STRIPE_WEBHOOK_SECRETwas not set when the process booted. Set it and redeploy; a running process will not pick it up. - 200 but nothing in the database: the event type is not enabled on the endpoint.
Every route returns 500 and the log says nothing
An environment variable is set to an empty string. ?? does not fall back on
"", so new URL("/x", "") throws, and in the root layout that takes every
page with it. Delete the variable rather than blanking it.
A NEXT_PUBLIC variable is undefined in the browser
It is marked Sensitive on Vercel, which means it is not inlined into the bundle. Change it to Encrypted and redeploy.
Borders are black and I never asked for black
You used a colour class whose token is not declared in @theme. Tailwind emits
nothing, and border falls back to currentColor. Declare the token. Check
the computed style rather than the screenshot; this one is easy to look at and
not see.
Copy shows {name} literally
Single braces. The message format wants {{name}}, and a single-braced
placeholder compiles with no warning. See
Internationalisation.
A message key exists but is undefined
It has an underscore. _ is the context separator, so meta_title compiles as
a variant of meta. Rename to camelCase.
The page is wider than the phone
Almost always a one-column grid sizing to max-content. Add grid-cols-1. The
next most common is a flex child without min-w-0, which will not shrink below
its content.
A form silently does nothing
Look for a router.refresh() firing near it. A navigation during a refresh
leaves the router holding a Server Components render with nowhere to go, and
the page it lands on can stop hydrating. React reports it as minified error
#441, which says nothing useful in production.
An animated element ignores its transform
Motion owns transform on any element it animates. A style={{ transform }}
on the same element is discarded. Animate the value instead, or wrap it.
Still stuck
Email hello@tryshipnow.com with what you expected, what happened, and the request id if there is one. A person reads it.
Something wrong or missing on this page? Tell us.