Common Lovable Issues

Step-by-step guides for the most common Lovable problems, written by real developers.

api

Stripe Webhook Signature Verification Failing

Stripe webhook endpoint receives events but signature verification fails. Webhook handler rejects legitimate events. Payment events aren't processed correctly. Security validation throws errors.

Stripe signs webhooks with your endpoint secret. Verification ensures events are authentic and haven't been tampered with. Signature mismatch indicates wrong secret or data corruption.

Testing Supabase Edge Functions Locally

Edge functions work in production but hard to test locally. Need to deploy to test. No local execution environment. Debugging is difficult without local testing.

Supabase CLI provides local development environment for testing functions before pushing to production.

Stripe Test vs Live Mode Confusion

Test payments work but production payments fail. Using test keys in production or live keys in development. Webhooks not firing in right environment. Keys mixed up causing transaction failures.

Stripe has separate test and live environments with different keys. Mixing keys between environments breaks payment flow.

Supabase Edge Function Timeouts or Fails to Execute

Edge function requests timeout after 120 seconds with 504 Gateway Timeout. Function doesn't execute or returns 500 error. Async operations timeout. Functions work locally but fail in production.

Supabase Edge Functions have strict timeout limits and require optimization for fast execution. Network calls and database queries must complete quickly.

Webhook Not Receiving Events from Supabase

Webhook endpoint configured in Supabase but never receives events. Database changes occur but webhook isn't triggered. Endpoint appears to work when tested but events don't arrive.

Webhooks require proper table configuration, filter setup, and endpoint accessibility. Events must be published and delivered correctly.

Third-Party API Calls Blocked by CORS

Calling third-party APIs from React app fails with CORS error. 'Access-Control-Allow-Origin' header missing. Works in backend but not client-side. Browser blocks cross-origin request.

CORS restrictions prevent client-side code from calling arbitrary APIs unless the API explicitly allows it. Solution requires using backend proxy or Edge Functions.

auth

Row Level Security (RLS) Policy Blocks All Database Access

Database queries fail with 'new row violates row-level security policy' or 'permission denied' errors. Users cannot read or write to tables despite having authentication credentials.

This occurs when RLS policies are too restrictive or missing entirely. RLS must be explicitly enabled per table and policies must allow the current auth context.

Supabase Anon Key Exposed in Client Code

Supabase anon key is visible in browser. Someone could copy it and use it to call Supabase API directly. Key is committed to Git. Security concern: data exposed via anon key.

Anon keys must be exposed on client but should never have direct table access. RLS policies protect data from unauthorized access even with key.

Auth State Lost During Navigation or Redirect

User logs in successfully but gets redirected to login page again. Auth state is lost after clicking a link or navigating. Session appears to end prematurely during redirect flow.

Auth state must persist during navigation. If state isn't properly restored from storage before redirect, users see login page again.

Supabase Admin Client Bypasses RLS for Backend

Need to perform operations that bypass RLS for server-side actions. Can't use regular client for certain admin operations. RLS blocking necessary backend logic.

Supabase admin client uses service role key which bypasses RLS. Use only in secure backend environment, never expose service role key to client.

OAuth Callback URL Mismatch with GitHub/Google Provider

OAuth authentication fails with error 'redirect_uri_mismatch' or callback page shows blank/error. Users cannot sign in via GitHub or Google because the configured redirect URL doesn't match.

OAuth providers validate that the redirect URL matches exactly what was registered. Any difference in protocol, domain, path, or query parameters will cause the mismatch error.

JWT Token Expires Silently Causing Unexpected Logout

Users experience sudden logout after being idle or when making requests. API calls start failing with 401 Unauthorized. The JWT token has expired but the app didn't refresh it before it became invalid.

By default, Supabase tokens expire after 1 hour. Without proper refresh token handling, expired tokens cause failures silently rather than triggering re-authentication flow.

Supabase Auth Session Not Persisting Across Page Reloads

After authenticating with Supabase, the user session disappears when the page is refreshed. Users are logged out unexpectedly, and the authentication state is not being maintained across browser sessions.

This typically happens because the auth session data is stored in memory only, rather than being persisted to localStorage or sessionStorage. When the page reloads, the in-memory state is lost.

database

Realtime Subscriptions Not Receiving Updates

Realtime subscriptions are set up but changes made by other users or external updates are not reflected in the UI. The app shows stale data even though data changed in the database.

Realtime requires explicit table replication configuration. Many tables have realtime disabled by default. Subscriptions also need to be set up before the page loads.

Data Not Saving to Supabase Database

When users submit forms or interact with the app, data appears to save locally but never reaches the database. Supabase inserts and updates silently fail without throwing errors. Data is lost on page reload.

This typically happens when insert/update operations fail due to RLS policies, missing required fields, type mismatches, or unhandled promise rejections.

Database Migration Fails During Deployment

Deployment fails because database migrations encounter errors. Schema changes conflict with existing data or migrations are applied in wrong order. Database becomes in inconsistent state, blocking the deployment.

Migrations must be designed carefully to handle existing data without data loss. Supabase maintains migration history and applies them sequentially.

Foreign Key Constraint Violation on Delete/Update

Attempting to delete or update records fails with 'foreign key constraint violation'. Child records reference the record being deleted, preventing the operation. This breaks the intended delete flow.

Foreign keys enforce referential integrity. When records are related, the database prevents orphaned references unless cascade rules are configured.

N+1 Query Problem Causing Slow Database Performance

App performance degrades as data grows. Loading 100 items runs 101 queries (1 for items + 1 per item for related data). Database becomes bottleneck with high latency and connection pool exhaustion.

N+1 occurs when fetching parent records, then looping to fetch each child separately, instead of joining in single query.

Querying Supabase JSON Columns Fails

Querying JSON columns returns no results or errors. Filter on nested JSON properties doesn't work. JSONB operators don't execute correctly.

PostgreSQL JSONB requires specific operators and syntax. Regular comparison doesn't work on JSON fields.

Database Connection Pool Exhaustion

Requests start failing with 'too many connections' or connection timeout errors. Error appears after app runs for a while or under load. Connection pool is exhausted.

Database has limited connections. Without proper connection management, connections leak and pool becomes exhausted.

RLS Allows SELECT But Blocks INSERT/UPDATE

Users can read data from table but cannot insert or update. 'permission denied' error on insert/update despite having select access. RLS policies inconsistently applied across operations.

Each database operation (SELECT, INSERT, UPDATE, DELETE) needs its own RLS policy. Common mistake is creating only SELECT policy and assuming others inherit.

deployment

Environment Variables Undefined in Production Build

API keys and configuration values are undefined in production. Supabase URL and API key return undefined, causing all API calls to fail. Works locally with .env.local but not in production.

Vite only exposes variables prefixed with VITE_ to the client. Production requires proper build-time or runtime environment setup.

CORS Error in Production Blocking Supabase Requests

API requests to Supabase fail with CORS error in production. 'Access-Control-Allow-Origin' header missing or not matching domain. Works locally but fails on deployed site.

CORS policy requires server to explicitly allow requests from client domain. Browser blocks cross-origin requests without proper headers.

Vite Build Produces Blank Page in Production

App works perfectly in development (npm run dev) but production build shows blank page (npm run build). No errors in console. Static assets fail to load with 404. JavaScript doesn't execute.

Production builds use optimized bundling that can expose issues hidden in dev mode. Base path, asset references, and build configuration mismatches cause blank pages.

Vite Hot Module Replacement (HMR) Connection Fails

Vite dev server starts but HMR connection fails with 'WebSocket connection failed' or 'net::ERR_CONNECTION_REFUSED'. Changes require manual page refresh instead of hot reload. Development experience is slow.

HMR requires WebSocket connection from browser to dev server. Network configuration or firewall can block the connection.

Supabase Storage Bucket CORS Error on Upload

File upload to Supabase Storage fails with CORS error. 'Access-Control-Allow-Origin' missing in response. Works with API key but not with RLS. Uploads blocked from production domain.

Supabase Storage requires CORS configuration and proper bucket settings for client-side uploads.

Dev Server HTTPS Needed for Secure Features

Features requiring HTTPS (geolocation, service workers, secure cookies) don't work on localhost:5173. Browser blocks insecure context APIs. Need to test HTTPS-only features in development.

Development typically uses HTTP, but some APIs require HTTPS. Self-signed certificates enable local HTTPS testing.

Vite Path Aliases Not Resolving in Build

Import aliases work in development (@/components) but fail in production build. Build fails with 'cannot find module' errors. Aliases not recognized by TypeScript or bundler.

Vite aliases require configuration in both vite.config.js and tsconfig.json. Missing either causes resolution failures.

Browser Cache Blocking App Updates

Users don't see app updates. Old JavaScript cached in browser. New features don't appear even after deployment. Cache headers prevent fresh content.

Browser caches static assets for performance. Without proper cache headers, users see stale code.

CSS-in-JS Styles Not Applying in Build

Styled-components, Emotion, or other CSS-in-JS works in dev but fails in production build. Styles disappear or don't apply. Class names don't match between server and client.

CSS-in-JS requires proper build configuration for server-side rendering and style extraction.

performance

Memory Leak from Unremoved Event Listeners

App memory usage grows over time. Performance degrades after extended use. DevTools memory profiler shows detached DOM nodes and event listeners. Browser tab becomes unresponsive.

Event listeners and subscriptions must be cleaned up when components unmount. Not removing them causes memory to accumulate.

Edge Function Cold Starts Causing Slow First Invocation

First call to Edge function is slow (2-5 seconds). Subsequent calls are fast. Cold start is noticeable for users. Function invocation time is unpredictable.

Serverless functions have cold start delay when first deployed or after inactivity. Function container spins up and loads dependencies.

Slow Initial Page Load and Time to Interactive

App takes 5+ seconds to load initial page. Blank white screen for extended period. Users see slow Time to First Contentful Paint (FCP) and Time to Interactive (TTI). Performance metrics are poor.

Page load speed depends on bundle size, network latency, and resource blocking. Optimizations include code splitting, lazy loading, and resource prioritization.

Image Optimization in Vite React vs Next.js

Coming from Next.js Image component, Vite React app loads unoptimized images. No automatic responsive images or lazy loading. Performance metrics show large image bytes.

Vite doesn't provide built-in image optimization like Next.js. Manual optimization or third-party tools needed.

Console Logging Slowing Down React Render

App performance noticeably slower with console.log in render. Removing logs makes app faster. Lots of logging output in DevTools console. Re-renders feel sluggish.

Console.log in render code executes on every render. Heavy logging causes measurable performance hit, especially during scrolling or animations.

Images Not Optimized Causing Large File Sizes

Images are loading large uncompressed files (5MB+). Page load is slow because image downloads are slow. High resolution images used even on mobile. No lazy loading.

Web images need optimization for format, size, and lazy loading. Unoptimized images account for >50% of page weight in many sites.

React Components Re-rendering Excessively

React components render on every state change even when their props don't change. Performance degrades with large lists. User interactions lag. DevTools Profiler shows excessive renders.

React re-renders components when props or state change. Unnecessary renders occur when parent state updates but child doesn't need the new data.

ui

Zustand State Not Updating in Components

Zustand state changes in store but components don't re-render. Updates work in other components but not in specific one. Selector hook returns stale data.

Zustand uses selector pattern to optimize re-renders. Improper selectors or store structure can cause missed updates.

Infinite Loop Caused by Missing Dependency

Browser becomes unresponsive. useEffect runs infinitely, making thousands of API calls. Network tab shows repeated requests. Browser memory increases until crash.

Infinite loops occur when dependency array is missing or incorrect, causing effect to run on every render, which updates state, causing re-render, repeating infinitely.

React Context Returns Undefined - Missing Provider

useContext() hook returns undefined even though context is defined. 'Cannot read property of undefined' errors when accessing context value. Context hook used outside provider scope.

Context consumers must be wrapped in their provider component. Using context outside provider scope or with missing provider returns undefined.

Dark Mode Not Toggling or Persisting

Dark mode toggle doesn't work or resets on page reload. Classes like 'dark:bg-gray-900' don't apply when dark mode is enabled. Theme preference not saved.

Dark mode requires class management on root element and localStorage persistence. Tailwind dark mode has multiple strategy options.

Form Submission Race Condition - Multiple Submissions or Lost Data

Clicking submit button multiple times creates duplicate records. Data submitted in wrong order due to async operations completing out of sequence. UI doesn't disable button during submission, causing race conditions.

Async form submissions need proper loading state to prevent duplicate submissions. Promises can resolve in any order, creating data inconsistencies.

Tailwind CSS Classes Not Applying or Conflicting

Tailwind classes are written correctly but styles don't apply to elements. Custom CSS conflicts with Tailwind. Class purging removes needed styles or adds unwanted ones.

Tailwind requires proper configuration of content paths for class scanning. Conflicts occur when CSS specificity issues override Tailwind utilities.

TypeScript Strict Mode Type Errors

Strict mode enabled but type errors prevent build. 'Cannot assign type' and 'missing type' errors. Null/undefined safety enforced. Code works but TypeScript won't compile.

Strict mode enforces stricter type checking. Requires more explicit typing but catches bugs early.

Unhandled React Error Crashing App

Single component error crashes entire app. White screen or error overlay shown to users. No graceful error handling. Error in child component propagates up.

React Error Boundaries catch errors in component trees. Prevents entire app from crashing due to single component error.

Tailwind Config Changes Not Reflecting in Dev

Changes to tailwind.config.js don't appear in development. Need to restart dev server to see theme changes. New colors, spacing, or custom utilities don't apply.

Vite should watch tailwind.config.js but sometimes changes aren't detected. Manual server restart required.

Mobile Layout Broken on Small Screens

App looks perfect on desktop but mobile screens show broken layout - text overlaps, buttons are cut off, content is unreadable. Horizontal scrolling required. Tailwind classes not applying correctly at smaller breakpoints.

Mobile responsiveness requires testing at actual mobile sizes and using Tailwind breakpoint prefixes (sm, md, lg) to adapt layout.

React Fragment Key Warning - No Key Prop

Warning: 'Each child in a list should have a unique key prop' when using fragments. Can't add key to <> syntax. Lists don't render correctly with fragment groups.

Fragments in lists need keys when rendering multiple elements per item. Shorthand <> syntax doesn't support keys.

React Key Prop Warning in Lists

Console warning: 'Each child in a list should have a unique key prop'. List re-renders cause wrong components to update. List items in wrong order after dynamic changes.

React uses keys to identify list items. Without unique keys, React reuses component instances incorrectly.

React Hook Dependency Warning - Stale Closures

ESLint shows 'missing dependency in useEffect' or 'exhaustive-deps' warning. Code works but warning suggests adding dependencies. Adding dependencies causes infinite loops. Stale closures reference old values.

React hooks require explicit dependency arrays to track when effects should re-run. Missing dependencies cause stale closures; extra ones cause infinite loops.

Modal or Dialog Not Closing Properly

Modal dialog stays open after clicking close button or outside. Multiple modals stack without closing previous ones. Backdrop remains visible even when modal closes. Z-index issues cause modals to appear behind other content.

Modal state must be properly managed with React state and backdrop click handlers. CSS z-index requires careful layering.

CSS Specificity Issues - Can't Override Styles

Styles can't be overridden despite being written after conflicting rules. !important needed everywhere. Third-party styles override custom styles. CSS cascade not working as expected.

CSS specificity determines which rule applies when conflicts occur. Higher specificity always wins. Understanding selector specificity is essential.

React Form Input Values Not Updating or Showing Stale Data

Form inputs don't update as user types. Values appear frozen. Submitted data shows old/stale values. Controlled inputs and state are out of sync.

React forms require proper state binding with onChange handlers and defaultValue or value props to keep inputs and state synchronized.

Stuck on Lovable?
Real developers can help.

You don't need to be technical. Just describe what's wrong and a verified developer will handle the rest.

Get Help