Skip to main content

Troubleshooting

Quick solutions to common issues when building with KwikSaaS.

Authentication Issues

Symptoms: Google/GitHub sign-in redirects to error page, console shows CORS or redirect errors, “Invalid callback URL” message.Solutions:Check Supabase URL Configuration: Go to Supabase Dashboard → Authentication → URL Configuration. Site URL should be http://localhost:3000 (exact match, no trailing slash). Redirect URLs must include http://localhost:3000/auth/callback.Verify OAuth provider settings: Callback URL in Google/GitHub must match Supabase’s provided URL. Client ID and Secret must be correct. Provider must be enabled in Supabase.Use localhost not 127.0.0.1: Supabase treats these as different origins. Always use http://localhost:3000.
Symptoms: Sign up completes but no email received, magic link never arrives, password reset email missing.Solutions:Check spam/junk folder first. Supabase rate limits: Free tier allows 4 emails/hour - wait or upgrade plan. Verify email settings in Authentication → Email Templates. Check Supabase Auth logs in Dashboard → Logs → Auth Logs.
Symptoms: User signs in but immediately logged out, dashboard shows sign-in page, session lost on page refresh.Solutions:Check NEXT_PUBLIC_SITE_URL matches the actual URL you’re accessing (include protocol). Verify middleware is running - check middleware.ts matcher patterns. Try incognito mode to rule out cookie issues, or clear site data.
Symptoms: Reset link shows error page, “Invalid or expired token” message.Solutions:Token expiry: Links expire after 24 hours - request a new one. Check auth callback: /auth/callback must be in Supabase Redirect URLs. Recovery flow requires type=recovery in URL. The callback sets a recovery cookie - if blocked, reset flow fails.

Payment Issues

Symptoms: Clicking pricing button shows error, console shows “Invalid price” or 400 status.Solutions:Verify price ID in Stripe Dashboard - ensure it starts with price_ and matches test/live mode. Check plan configuration in src/lib/payments/plans.ts has matching stripePriceIds. Stripe mode mismatch: test keys only work with test products.
Symptoms: Stripe Dashboard shows failed webhooks, console shows “No signatures found matching”, database not updating after payment.Solutions:For local development: Restart stripe listen command, copy the new whsec_... secret, update STRIPE_WEBHOOK_SECRET in .env.local, restart dev server.For production: Go to Stripe → Developers → Webhooks, verify endpoint URL is correct, use the webhook’s signing secret (not API key).
Symptoms: Payment successful in Stripe, user doesn’t show as subscribed, user_subscriptions table empty.Solutions:Ensure webhook listener is running: stripe listen --forward-to localhost:3000/api/webhooks/stripe. Check Stripe webhook logs in Developers → Webhooks → Recent events. Verify database migrations with npx supabase db push. Check server logs for errors in webhook handler.
Symptoms: “Manage subscription” button doesn’t work, error creating portal session.Solutions:User needs stripe_customer_id in user_subscriptions table - customer is created on first checkout. Enable portal in Stripe Settings → Billing → Customer portal. User must be authenticated - portal requires active session.

Database Issues

Symptoms: “relation does not exist” errors, dashboard shows database errors, can’t insert/read data.Solutions:Run migrations: npx supabase db push. Or manually execute SQL from supabase/migrations/*.sql in Supabase SQL Editor. Check connection - verify NEXT_PUBLIC_SUPABASE_URL is correct and project is active (not paused).
Symptoms: Empty data returned from queries, “new row violates row-level security policy”, works in Supabase dashboard but not app.Solutions:Check user authentication - RLS requires authenticated session. Use correct client: client-side uses anon key with RLS, server-side service key bypasses RLS. Review policies in Supabase → Authentication → Policies.

Build and Deploy Issues

Symptoms: npm run build fails, TypeScript errors in console, deploy fails on Vercel.Solutions:Run type check locally: npm run lint and npx tsc --noEmit. Supabase types may need regeneration with npx supabase gen types typescript. Build may fail if env vars are missing - set all required vars in deployment platform.
Symptoms: undefined values in app, features not working in production, works locally but not deployed.Solutions:Client-side variables must start with NEXT_PUBLIC_. Restart dev server after changes. Server-side variables are available in API routes and server components. For Vercel: add all variables in dashboard and redeploy after adding new variables.
Symptoms: Changes not appearing after deploy, Vercel shows successful but outdated.Solutions:Clear Vercel cache by triggering new deployment with “Redeploy” → Clear cache. Check you’re deploying the correct branch. Review build logs for errors.

Development Issues

Symptoms: Changes require manual refresh, fast refresh errors in console.Solutions:Check for syntax errors - they can break hot reload. Restart dev server with npm run dev. Clear Next.js cache: rm -rf .next && npm run dev.
Symptoms: Classes have no effect, styles work locally but not in production.Solutions:Check content configuration in tailwind.config.ts. Use full class names (not computed). Use cn() helper for conditional classes. Clear cache: rm -rf .next && npm run dev.
Symptoms: Import errors in console, “Cannot find module” messages.Solutions:Reinstall dependencies: rm -rf node_modules && npm install. Check path aliases - imports should use @/ prefix. Verify tsconfig.json paths. Note that Linux/macOS are case-sensitive.

Email Issues

Symptoms: No emails received from app, Resend dashboard shows no activity.Solutions:Check API key - RESEND_API_KEY must start with re_. Domain must be verified in Resend with DNS records (SPF, DKIM). RESEND_FROM_EMAIL must use verified domain or @resend.dev for testing.
Symptoms: Emails sent but go to spam, low deliverability.Solutions:Complete domain verification with all DNS records (SPF, DKIM, DMARC) - wait up to 48 hours for propagation. Avoid spam triggers: no all caps in subject, include unsubscribe link. Use custom domain instead of @resend.dev in production.

Still Stuck?

When reporting issues, include: error messages (full text), steps to reproduce, environment (local/production), and relevant environment variables (without secrets).