supabase-common-errors
Troubleshooting guide for identifying and resolving Supabase error codes.
Install
mkdir -p .claude/skills/supabase-common-errors && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/1228" && unzip -o skill.zip -d .claude/skills/supabase-common-errors && rm skill.zipInstalls to .claude/skills/supabase-common-errors
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Diagnose and fix Supabase errors across PostgREST, PostgreSQL, Auth,Key capabilities
- →Capture Supabase error objects from SDK calls.
- →Identify the error layer and code (PostgREST, PostgreSQL, Auth, Storage).
- →Apply fixes for common errors like expired JWTs or RLS violations.
- →Verify fixes by re-running the original operation.
- →Implement guard code to prevent null-data bugs.
How it works
The skill provides a workflow to capture Supabase error objects, classify them by layer and code, and apply documented fixes to resolve issues.
Inputs & outputs
When to use supabase-common-errors
- →Resolving PostgREST 403 errors
- →Debugging RLS policy failures
- →Fixing auth token errors
About this skill
Supabase Common Errors
Overview
Diagnostic guide for Supabase errors across PostgREST (PGRST*), PostgreSQL (numeric codes), Auth, Storage, and Realtime. Identify the error layer, trace the root cause, and apply the correct fix — every SDK call returns { data, error } where data is null when error exists.
The workflow is three steps: capture the error object, classify it by layer and code, then apply and verify the fix. Full step-by-step code lives in the diagnostic walkthrough; complete lookup tables are in the error reference.
Prerequisites
@supabase/supabase-jsinstalled (npm install @supabase/supabase-js)SUPABASE_URLandSUPABASE_ANON_KEY(orSUPABASE_SERVICE_ROLE_KEY) configured- Access to Supabase Dashboard (for log inspection and SQL Editor)
- Supabase CLI installed for local development (
npx supabase --version)
Instructions
Step 1 — Capture the Error Object
Every Supabase SDK call returns a { data, error } tuple. Never assume data exists — always destructure and check error first, because data is null whenever error is set.
const { data, error } = await supabase.from('todos').select('*')
if (error) {
console.error(`[${error.code}] ${error.message}`)
return // data is null here — do not touch it
}
console.log(`Found ${data.length} rows`)
If error is undefined rather than null, upgrade to @supabase/[email protected]. See the walkthrough for the full guard pattern.
Step 2 — Identify the Error Layer and Code
Match the code prefix to its subsystem, then look it up in the Error Handling tables below:
PGRST*→ PostgREST (API gateway: JWT, query parsing, schema)- 5-digit numeric (e.g.
42501,23505) → PostgreSQL engine (RLS, constraints, migrations) AuthApiError→ Auth service (credentials, confirmation, token expiry)StorageApiError→ Storage service (bucket, RLS onstorage.objects, size limits)
A missing code usually means the HTTP status is the signal: 401 → bad/missing SUPABASE_ANON_KEY; 500 → an unhandled exception in a database function. A paste-ready diagnoseSupabaseError() classifier is in the walkthrough.
Step 3 — Apply the Fix and Verify
Apply the fix from the matching Error Handling table, then re-run the original operation to confirm. Common recoveries:
- Refresh an expired JWT (
PGRST301) withsupabase.auth.refreshSession(). - Confirm an RLS block (
42501) by re-querying with the service-role client before correcting the policy. - After a migration, reload the PostgREST schema cache (Dashboard → Settings → API → "Reload schema cache", or
NOTIFY pgrst, 'reload schema').
Full before/after fix code for both cases is in the walkthrough.
Output
Deliverables after applying this skill:
- Error identified by code and layer (PostgREST, PostgreSQL, Auth, Storage, Realtime)
- Root cause isolated using the diagnostic helper or manual code inspection
- Fix applied from the Error Handling table and verified against the original failing operation
- Guard code in place (
if (error)checks) preventing silent null-data bugs
Error Handling
The two most-cited layers are inline below. Auth, Storage, and Realtime tables are in the full error reference.
PostgREST API Errors (PGRST*)
| Code | HTTP | Meaning | Root Cause | Fix |
|---|---|---|---|---|
PGRST301 | 401 | JWT expired or invalid | SUPABASE_ANON_KEY is wrong, or the user session expired | Verify SUPABASE_ANON_KEY matches the project; call supabase.auth.refreshSession() |
PGRST302 | 401 | Missing Authorization header | Client created without a key, or middleware stripped the header | Pass SUPABASE_ANON_KEY to createClient(); check proxy/CDN config |
PGRST116 | 406 | No rows returned for .single() | Query matched 0 rows but .single() expects exactly 1 | Use .maybeSingle() for optional lookups, or check filters |
PGRST200 | 400 | Invalid query parameters | Malformed filter, bad operator, or invalid column reference | Check filter syntax: .eq('col', val) not .eq('col = val') |
PGRST204 | 400 | Column not found | Column name doesn't exist in the table or view | Verify column exists with supabase gen types typescript; check for typos |
PGRST000 | 503 | Connection pool exhausted | Too many concurrent connections from serverless functions | Enable pgBouncer (Supavisor) in project settings; reduce connection count |
PostgreSQL Database Errors (5-digit codes)
| Code | Meaning | Root Cause | Fix |
|---|---|---|---|
42501 | RLS policy violation | Row-level security is blocking the operation for this user | Add or fix the RLS policy; test with service role to confirm |
23505 | Unique constraint violation | INSERT/UPDATE conflicts with an existing row | Use .upsert({ onConflict: 'column' }) or check existence first |
23503 | Foreign key violation | Referenced row doesn't exist in the parent table | Insert the parent row first, or check the foreign key value |
42P01 | Table or relation doesn't exist | Migration not applied, or wrong schema | Run supabase db push; verify schema with \dt in SQL Editor |
42703 | Column doesn't exist | Schema out of sync with code | Regenerate types: supabase gen types typescript --local > types/supabase.ts |
57014 | Query cancelled (statement timeout) | Query took longer than statement_timeout | Add indexes; simplify the query; increase timeout in postgresql.conf |
Examples
The most common failure — calling .single() on optional data — is inline below. Three more worked examples (upsert to dodge 23505, Realtime subscription error handling, and serverless pool exhaustion) are in the examples reference.
Handling .single() on optional data (PGRST116)
// BAD — throws PGRST116 when the user has no profile row
const { data: profile } = await supabase
.from('profiles').select('*').eq('user_id', userId).single()
// GOOD — returns null instead of erroring
const { data: profile, error } = await supabase
.from('profiles').select('*').eq('user_id', userId).maybeSingle()
if (!profile) {
await supabase.from('profiles').insert({ user_id: userId, display_name: 'New User' })
}
Resources
- Full diagnostic walkthrough — every capture/classify/fix code block
- Complete error reference — Auth, Storage, and Realtime tables
- Worked examples — upsert, Realtime, serverless pooling
- Supabase JavaScript SDK Reference
- PostgREST Error Codes
- PostgreSQL Error Codes
- RLS Debugging Guide
- Supabase Realtime Troubleshooting
- Supabase Status Page
Next Steps
- Use
supabase-debug-bundleto generate a full diagnostic snapshot when errors persist after applying these fixes. - Use
supabase-security-basicsto audit your RLS policies and prevent42501errors proactively. - Use
supabase-known-pitfallsfor edge cases and SDK behavior that can cause subtle bugs. - Use
supabase-observabilityto set up logging and alerting so you catch errors before users report them.
Prerequisites
Limitations
- →A missing error code usually means the HTTP status is the signal.
- →Querying with .single() expects exactly one row.
- →Too many concurrent connections can exhaust the connection pool.
How it compares
This skill offers a structured diagnostic and resolution process for Supabase errors, which is more systematic than ad-hoc debugging.
Compared to similar skills
supabase-common-errors side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| supabase-common-errors (this skill) | 4 | 27d | Review | Intermediate |
| data-safety-auditor | 3 | 7mo | No flags | Advanced |
| supabase-postgres-best-practices | 4 | 6mo | No flags | Intermediate |
| supabase-policy-guardrails | 3 | 27d | Review | Advanced |
Try saying
Example prompts that trigger this skill in your AI assistant.
More by jeremylongshore
View all by jeremylongshore →You might also like
data-safety-auditor
ananddtyagi
Comprehensive data safety auditor for Vue 3 + Pinia + IndexedDB + PouchDB applications. Detects data loss risks, sync issues, race conditions, and browser-specific vulnerabilities with actionable remediation guidance.
supabase-postgres-best-practices
davila7
Postgres performance optimization and best practices from Supabase. Use this skill when writing, reviewing, or optimizing Postgres queries, schema designs, or database configurations.
supabase-policy-guardrails
jeremylongshore
Implement Supabase lint rules, policy enforcement, and automated guardrails. Use when setting up code quality rules for Supabase integrations, implementing pre-commit hooks, or configuring CI policy checks for Supabase best practices. Trigger with phrases like "supabase policy", "supabase lint", "supabase guardrails", "supabase best practices check", "supabase eslint".
supabase-known-pitfalls
jeremylongshore
Execute identify and avoid Supabase anti-patterns and common integration mistakes. Use when reviewing Supabase code for issues, onboarding new developers, or auditing existing Supabase integrations for best practices violations. Trigger with phrases like "supabase mistakes", "supabase anti-patterns", "supabase pitfalls", "supabase what not to do", "supabase code review".
supabase-incident-runbook
jeremylongshore
Execute Supabase incident response procedures with triage, mitigation, and postmortem. Use when responding to Supabase-related outages, investigating errors, or running post-incident reviews for Supabase integration failures. Trigger with phrases like "supabase incident", "supabase outage", "supabase down", "supabase on-call", "supabase emergency", "supabase broken".
backend-dev
marmelab
Coding practices for backend development in Atomic CRM. Use when deciding whether backend logic is needed, or when creating/modifying database migrations, views, triggers, RLS policies, edge functions, or custom dataProvider methods that call Supabase APIs.