The 10 Most Common Errors
The errors every beginner sees repeatedly — with the exact error text, what it means in plain English, and how to fix it.
You will see these errors. Repeatedly. Every developer does, especially when starting out. The difference between someone who spends an hour confused and someone who fixes it in five minutes is knowing what these messages mean.
This page is your reference. When you see a red error in the Console or a failed request in the Network tab, find it here first.
Why First: The Error That Sent You in Circles
You deploy your first Supabase-connected form. You fill it in. You click Submit. You see a red error in the Console: TypeError: Cannot read properties of undefined (reading 'map').
You Google the exact error text. You get 47 Stack Overflow results. Half say it's a JavaScript versioning issue. A quarter say it's a Node.js problem. None of them explain what's actually happening in your specific case.
Here is what's actually happening: your data hasn't loaded yet, but your code is trying to loop through it. One line of code fixes it. But without knowing that translation — "undefined reading map = data not loaded yet" — you cannot know that.
This page gives you the translation for the 10 errors you will encounter most.
Error 1: Cannot read properties of undefined (reading 'map')
Where you see it: Console tab, red error
Full error text:
What it means in plain English: You tried to use .map() to loop through a list, but the list is currently undefined — it hasn't loaded yet. This almost always happens when Supabase data is still fetching and your component tries to render before the data arrives.
Excel analogy: Like trying to run a formula on a cell that shows #N/A — the value isn't there yet, so the formula crashes.
How to fix it:
Error 2: 404 Not Found (Network Tab)
Where you see it: Network tab, red status code 404
What it means in plain English: Your app tried to reach a URL that doesn't exist. Either the URL is wrong, or the resource was moved or deleted. For Supabase calls, this usually means the table name in the URL is wrong or the Supabase project URL is misconfigured.
How to diagnose:
- Click the 404 request in the Network tab
- Look at the full URL in the Headers tab
- Compare it to your expected Supabase URL and table name
Common causes:
- Typo in table name:
supabase.from('job')instead ofsupabase.from('jobs') - Wrong Supabase URL in
.env(wrong project, or URL not set at all) - Edge function name misspelled:
supabase.functions.invoke('send-eamil')(typo)
How to fix it: Check the URL in the Network tab. Fix the table name, function name, or .env value accordingly.
Error 3: 401 Unauthorized (Network Tab)
Where you see it: Network tab, red status code 401
What it means in plain English: The request reached the server, but the server doesn't know who you are. You are not authenticated — either you haven't logged in, or your auth token has expired, or the token isn't being sent with the request.
How to diagnose:
- Click the 401 request in the Network tab
- Go to the Headers tab
- Check if
Authorization: Bearer eyJ...is present in the Request Headers - Check the Response tab for the error message (often
JWT expiredorJWT invalid)
How to fix it:
- If the Authorization header is missing: your Supabase client isn't attaching the session. Check how you initialized the Supabase client.
- If the token is expired: the session refresh isn't working. Ensure
autoRefreshToken: truein your Supabase client config. - If the user just isn't logged in: add an auth check before the request is made.
Error 4: 403 Forbidden — RLS Blocking the Query (Network Tab)
Where you see it: Network tab, red status code 403, or sometimes 200 with an empty array when you expected data
What it means in plain English: You are logged in, but your Row Level Security policy is preventing this specific operation. The user is authenticated but doesn't have permission for what they're trying to do — or to see the data they're trying to read.
Response body you'll see:
Or for a SELECT that RLS is silently blocking: An empty array when you expected data often means RLS filtered out all rows.
How to fix it: Go to the Supabase dashboard → Authentication → Policies. Find the table mentioned in the error. Check your policies — specifically:
- Is there a SELECT policy for the user's role?
- Does the
usingclause match the user's actual data (e.g., checkingauth.uid() = user_id)? - Is RLS enabled when it shouldn't be for this table, or vice versa?
401 vs 403 — The most important distinction to memorize:
- 401 = Not authenticated. The server doesn't know who you are.
- 403 = Authenticated but not allowed. The server knows who you are but says no.
Fix them completely differently.
Error 5: CORS Error
Where you see it: Console tab, red error
Full error text:
What it means in plain English: CORS (Cross-Origin Resource Sharing) is a browser security feature. Your browser is blocking the request because the server hasn't explicitly said "requests from localhost:5173 are allowed."
For Supabase, this rarely happens with the standard Supabase client because Supabase handles CORS correctly by default. When it does appear, it usually means:
- You're calling a custom edge function that doesn't return CORS headers
- You're making a raw
fetch()call to Supabase instead of using the Supabase client
How to fix it:
- If it's an edge function: add CORS headers to the edge function response (the Supabase edge function templates include a
corsHeadersobject — use it). - If it's a raw
fetch()call: switch to the Supabase client instead. - Check the Supabase dashboard → Settings → API → CORS settings to ensure your domain is allowed.
Error 6: Failed to fetch
Where you see it: Console tab, or in your React Query error state
Full error text:
What it means in plain English: The network request didn't reach the server at all. Either your internet is down, the dev server isn't running, or the URL is completely unreachable.
How to diagnose:
- Is your Vite dev server running? Check the terminal where you ran
npm run dev— is it still running? - Can you open the Supabase URL directly in a browser tab?
- Is the URL in the request (visible in the Network tab) malformed (missing
https://, extra slashes, etc.)?
How to fix it:
- Restart your dev server
- Check your
.envfile — isVITE_SUPABASE_URLset correctly? - If the URL looks wrong in the Network tab, check how you're constructing it in code
Error 7: Unexpected token < in JSON at position 0
Where you see it: Console tab, or in the Network tab Response panel
Full error text:
What it means in plain English: Your app expected a JSON response from the server, but received an HTML page instead. This almost always means the server returned an error page (like a 404 "Not Found" HTML page) and your code tried to parse that HTML as JSON and failed.
How to diagnose:
- Find the failing request in the Network tab
- Check the Status — it will usually be 404 or 500 (not 200)
- Look at the Response tab — you will see an HTML page, not JSON
How to fix it: Fix the underlying 404 or 500 error. The JSON parsing error is a symptom — the real problem is that the URL doesn't exist or the server crashed.
Error 8: Objects are not valid as a React child
Where you see it: Console tab, red error
Full error text:
What it means in plain English: You tried to render a JavaScript object directly in JSX. React can render strings, numbers, and arrays of those — but not plain objects.
Common cause:
How to fix it: Add .property_name to render a specific field from the object, or call .toString() or a formatting function to convert it to a string.
Error 9: React Hook useEffect has a missing dependency
Where you see it: Console tab, yellow warning (not a crash — ESLint warning)
Full error text:
What it means in plain English: Your useEffect hook uses a variable (userId in this example) but that variable isn't listed in the dependency array []. React is warning you that the effect might behave incorrectly — it reads a value at setup time but won't re-run if that value changes later.
Important: This is usually a sign you should use React Query instead of useEffect for data fetching. If you're using useEffect to fetch data, that is where the problem starts.
If you do need useEffect:
Error 10: Maximum update depth exceeded
Where you see it: Console tab, red error, usually causes an infinite loop that freezes the browser tab
Full error text:
What it means in plain English: Your component is stuck in an infinite re-render loop. Something is updating state, which triggers a re-render, which updates state again, infinitely. The browser catches this after a few hundred iterations and throws this error.
Common cause — missing or wrong dependency array:
Another common cause — object or array as a dependency:
How to fix it: Find the useEffect that is causing the loop. Check its dependency array. Make sure nothing in the dependency array creates a new reference on every render. If you're struggling with this, replace the useEffect with a React Query useQuery hook — React Query handles this correctly by design.
Quick Reference Table
| Error | Tab | Most Likely Cause | First Thing to Check |
|---|---|---|---|
| Cannot read properties of undefined | Console | Data not loaded yet | Add ?. or loading check |
| 404 Not Found | Network | Wrong URL or table name | Full URL in Headers tab |
| 401 Unauthorized | Network | Not logged in, token expired | Authorization header present? |
| 403 Forbidden | Network | RLS policy blocking | Supabase Dashboard → Policies |
| CORS error | Console | Missing CORS headers on edge function | Edge function CORS headers |
| Failed to fetch | Console | Dev server down or bad URL | Is npm run dev still running? |
Unexpected token < | Console | Server returned HTML not JSON | Check status code in Network |
| Objects are not valid as child | Console | Rendering an object instead of a string | Add .property_name |
| Missing dependency warning | Console | useEffect dependency array | Add the variable to the array |
| Maximum update depth | Console | Infinite re-render loop | Check useEffect dependencies |