supabase-debug-bundle
Automates the collection of Supabase diagnostic bundles, including connection and auth logs, for support escalation.
Install
mkdir -p .claude/skills/supabase-debug-bundle && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/6023" && unzip -o skill.zip -d .claude/skills/supabase-debug-bundle && rm skill.zipInstalls to .claude/skills/supabase-debug-bundle
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.
Collect Supabase diagnostic info for troubleshooting and support tickets.Key capabilities
- →Collect Supabase diagnostic information
- →Test Supabase connectivity to REST and Auth endpoints
- →Probe Realtime, Storage, and RLS subsystems
- →Package diagnostics into a single archive
- →Identify SDK and CLI versions
How it works
The skill collects diagnostic data by testing various Supabase services and packaging the results into an archive. It checks SDK versions and environment variables.
Inputs & outputs
When to use supabase-debug-bundle
- →Debug Supabase connection failures
- →Prepare diagnostic logs for support tickets
- →Audit Supabase RLS policy configurations
- →Verify Realtime and Storage service status
About this skill
Supabase Debug Bundle
Overview
Collect a comprehensive, redacted diagnostic bundle from a Supabase project. Tests connectivity, auth, Realtime, Storage, RLS policy behavior, and database health — then packages everything into a single archive safe for sharing with Supabase support.
Current State
!node --version 2>/dev/null || echo 'Node.js not found'
!npx supabase --version 2>/dev/null || echo 'Supabase CLI not found'
!npm list @supabase/supabase-js 2>/dev/null | grep supabase || echo '@supabase/supabase-js not installed'
Prerequisites
- Node.js 18+ with
@supabase/supabase-jsv2 installed in the project - Supabase CLI installed (
npm i -g supabaseornpx supabase) - Environment variables set:
SUPABASE_URLandSUPABASE_ANON_KEY(minimum);SUPABASE_SERVICE_ROLE_KEYfor full diagnostics - Project linked via
supabase link --project-ref <ref>(for CLI commands)
Instructions
Step 1: Gather Environment and Connectivity
Collect SDK version, project URL, key type, and test basic connectivity against the REST and Auth endpoints.
import { createClient } from '@supabase/supabase-js'
const url = process.env.SUPABASE_URL!
const anonKey = process.env.SUPABASE_ANON_KEY!
const serviceKey = process.env.SUPABASE_SERVICE_ROLE_KEY
// Identify which key is in use
const keyType = serviceKey ? 'service_role' : 'anon'
const supabase = createClient(url, serviceKey ?? anonKey, {
auth: { autoRefreshToken: false, persistSession: false }
})
const diagnostics: Record<string, unknown> = {}
// 1a — SDK + environment
diagnostics.environment = {
supabase_js_version: require('@supabase/supabase-js/package.json').version,
node_version: process.version,
project_url: url.replace(/https:\/\/([^.]+)\..*/, 'https://$1.***'),
key_type: keyType,
timestamp: new Date().toISOString(),
}
// 1b — REST API connectivity
const restStart = Date.now()
const restRes = await fetch(`${url}/rest/v1/`, {
headers: { apikey: anonKey, Authorization: `Bearer ${anonKey}` },
})
diagnostics.rest_api = {
status: restRes.status,
latency_ms: Date.now() - restStart,
ok: restRes.ok,
}
// 1c — Auth health
const authStart = Date.now()
const { data: sessionData, error: sessionErr } = await supabase.auth.getSession()
diagnostics.auth = {
status: sessionErr ? `error: ${sessionErr.message}` : 'ok',
has_session: !!sessionData?.session,
latency_ms: Date.now() - authStart,
}
// 1d — Database connectivity probe
const dbStart = Date.now()
const { error: dbErr } = await supabase.from('_test_ping').select('*').limit(1)
diagnostics.database = {
// 42P01 = table doesn't exist, which proves the connection works
status: (!dbErr || dbErr.code === '42P01') ? 'connected' : `error: ${dbErr.code}`,
latency_ms: Date.now() - dbStart,
}
console.log(JSON.stringify(diagnostics, null, 2))
What to check: REST API should return 200. Auth should return ok. Database probe returning 42P01 (relation not found) is normal — it confirms the PostgREST connection works.
Step 2: Test Realtime, Storage, and RLS
Probe the three subsystems that cause the most support tickets.
// 2a — Realtime subscription test
const realtimeResult = await new Promise<Record<string, unknown>>((resolve) => {
const timeout = setTimeout(() => {
resolve({ status: 'timeout', detail: 'No SUBSCRIBED event within 5s' })
}, 5000)
const channel = supabase.channel('debug-probe')
channel.subscribe((status) => {
if (status === 'SUBSCRIBED') {
clearTimeout(timeout)
channel.unsubscribe()
resolve({ status: 'ok', detail: 'Channel subscribed successfully' })
} else if (status === 'CHANNEL_ERROR') {
clearTimeout(timeout)
channel.unsubscribe()
resolve({ status: 'error', detail: 'CHANNEL_ERROR on subscribe' })
}
})
})
diagnostics.realtime = realtimeResult
// 2b — Storage bucket listing
const { data: buckets, error: storageErr } = await supabase.storage.listBuckets()
diagnostics.storage = {
status: storageErr ? `error: ${storageErr.message}` : 'ok',
bucket_count: buckets?.length ?? 0,
buckets: buckets?.map((b) => ({ name: b.name, public: b.public })) ?? [],
}
// 2c — RLS comparison: anon vs service_role
// Query the same table with both key types to detect RLS misconfiguration
if (serviceKey) {
const anonClient = createClient(url, anonKey, {
auth: { autoRefreshToken: false, persistSession: false },
})
// Pick the first public table from pg_tables (or fall back)
const { data: tables } = await supabase
.from('information_schema.tables' as any)
.select('table_name')
.eq('table_schema', 'public')
.limit(1)
const testTable = tables?.[0]?.table_name
if (testTable) {
const { count: anonCount } = await anonClient
.from(testTable)
.select('*', { count: 'exact', head: true })
const { count: serviceCount } = await supabase
.from(testTable)
.select('*', { count: 'exact', head: true })
diagnostics.rls = {
table: testTable,
anon_visible_rows: anonCount ?? 0,
service_role_visible_rows: serviceCount ?? 0,
rls_active: (anonCount ?? 0) !== (serviceCount ?? 0),
}
} else {
diagnostics.rls = { status: 'skipped', detail: 'No public tables found' }
}
} else {
diagnostics.rls = { status: 'skipped', detail: 'No service_role key — cannot compare' }
}
What to check: Realtime should reach SUBSCRIBED within 5 seconds. Storage should list buckets without error. RLS comparison showing identical row counts for anon and service_role on a table you expect to be protected means RLS policies may be missing.
Step 3: Collect Database Health and Package the Bundle
Pull database statistics via the Supabase CLI inspect commands and the platform status page, then archive everything.
#!/bin/bash
set -euo pipefail
BUNDLE_DIR="supabase-debug-$(date +%Y%m%d-%H%M%S)"
mkdir -p "$BUNDLE_DIR"
# 3a — Supabase CLI status (local dev)
npx supabase status > "$BUNDLE_DIR/cli-status.txt" 2>&1 || echo "CLI status unavailable (not linked or no local dev)" > "$BUNDLE_DIR/cli-status.txt"
# 3b — Database inspection via CLI
npx supabase inspect db table-sizes > "$BUNDLE_DIR/table-sizes.txt" 2>&1 || true
npx supabase inspect db index-usage > "$BUNDLE_DIR/index-usage.txt" 2>&1 || true
npx supabase inspect db cache-hit > "$BUNDLE_DIR/cache-hit.txt" 2>&1 || true
npx supabase inspect db seq-scans > "$BUNDLE_DIR/seq-scans.txt" 2>&1 || true
npx supabase inspect db long-running-queries > "$BUNDLE_DIR/long-queries.txt" 2>&1 || true
npx supabase inspect db bloat > "$BUNDLE_DIR/bloat.txt" 2>&1 || true
npx supabase inspect db replication-slots > "$BUNDLE_DIR/replication.txt" 2>&1 || true
# 3c — Platform status page
curl -sf https://status.supabase.com/api/v2/status.json \
| python3 -m json.tool > "$BUNDLE_DIR/platform-status.json" 2>/dev/null \
|| echo '{"error": "Could not reach status.supabase.com"}' > "$BUNDLE_DIR/platform-status.json"
# 3d — Redact secrets from all collected files
find "$BUNDLE_DIR" -type f -exec sed -i \
-e 's/eyJ[A-Za-z0-9_-]\{20,\}\(\.[A-Za-z0-9_-]*\)*/[JWT_REDACTED]/g' \
-e 's/sbp_[A-Za-z0-9]\{20,\}/[SBP_KEY_REDACTED]/g' \
-e 's/[A-Za-z0-9._%+-]\+@[A-Za-z0-9.-]\+\.[A-Za-z]\{2,\}/[EMAIL_REDACTED]/g' {} +
# 3e — Package
tar czf "${BUNDLE_DIR}.tar.gz" "$BUNDLE_DIR"
echo "Debug bundle created: ${BUNDLE_DIR}.tar.gz"
echo "Contents:"
ls -lh "$BUNDLE_DIR"/
What to check: Review cache-hit.txt — index and table hit rates below 99% indicate memory pressure. bloat.txt values above 50% on large tables warrant a VACUUM. seq-scans.txt highlights tables needing indexes.
Output
The skill produces supabase-debug-YYYYMMDD-HHMMSS.tar.gz containing:
| File | Contents |
|---|---|
cli-status.txt | Local Supabase stack status (services, ports, URLs) |
table-sizes.txt | All tables with row counts and disk usage |
index-usage.txt | Index scan frequency — unused indexes are candidates for removal |
cache-hit.txt | Buffer cache and index cache hit ratios |
seq-scans.txt | Tables with high sequential scan counts (missing indexes) |
long-queries.txt | Currently running queries over the duration threshold |
bloat.txt | Table and index bloat percentages |
replication.txt | Replication slot status (relevant for Realtime) |
platform-status.json | Supabase platform health from status.supabase.com |
Plus the TypeScript diagnostics output (connectivity, auth, Realtime, Storage, RLS) printed to stdout.
All JWT tokens, Supabase project keys (sbp_*), and email addresses are automatically redacted before archiving.
Error Handling
| Symptom | Cause | Fix |
|---|---|---|
REST API returns 401 | Invalid or expired anon key | Regenerate key in Dashboard > Settings > API |
REST API returns 000 or times out | Wrong SUPABASE_URL or project paused | Verify URL; unpause project in Dashboard |
Realtime returns CHANNEL_ERROR | WebSocket blocked by firewall/proxy | Check corporate proxy; try from a different network |
| Realtime times out (5s) | Realtime addon not enabled or quota hit | Enable Realtime on the table in Dashboard > Database > Replication |
Storage listBuckets returns 403 | RLS enabled on storage without policy | Add a storage policy or use service_role key |
supabase inspect db fails | CLI not linked to remote project | Run supabase link --project-ref <ref> first |
cache-hit below 95% | Database instance too small for workload | Upgrade compute size or optimize queries |
| RLS shows identical counts | No RLS policies on the table | Add policies via ALTER TABLE ... ENABLE ROW LEVEL SECURITY |
pg_stat_statements not available | Extension not enabled | Enable in Dashboard > Database > Extensions |
Examples
Quick connectivity check (no service key needed):
import { createClient } from '@supabase/
---
*Content truncated.*
Prerequisites
How it compares
This skill automates the collection of complete Supabase diagnostic data, which is more thorough than manual checks for troubleshooting and support.
Compared to similar skills
supabase-debug-bundle side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| supabase-debug-bundle (this skill) | 1 | 27d | Caution | Beginner |
| redis-inspect | 6 | 6mo | Review | Beginner |
| optimizing-performance | 1 | 2mo | Review | Intermediate |
| semaphore-third-party-licenses | 0 | 2mo | Review | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
More by jeremylongshore
View all by jeremylongshore →You might also like
redis-inspect
civitai
Inspect Redis cache keys, values, and TTLs for debugging. Supports both main cache and system cache. Use for debugging cache issues, checking cached values, and monitoring cache state. Read-only by default.
optimizing-performance
CloudAI-X
Analyzes and optimizes application performance across frontend, backend, and database layers. Use when diagnosing slowness, improving load times, optimizing queries, reducing bundle size, or when asked about performance issues.
semaphore-third-party-licenses
semaphoreui
>
hiddenroom-supabase
cuvo1903-ctrl
Hidden Room Supabase backend skill for migrations, generated database types, Edge Functions, RLS policies, auth/profile sync, storage buckets, Stripe integration, cloud_jobs, and database documentation. Use when editing supabase/migrations, supabase/functions, database.types.ts, or Supabase-backed f
backend-security-coder
sickn33
Expert in secure backend coding practices specializing in input validation, authentication, and API security. Use PROACTIVELY for backend security implementations or security code reviews.
supabase-common-errors
jeremylongshore
Execute diagnose and fix Supabase common errors and exceptions. Use when encountering Supabase errors, debugging failed requests, or troubleshooting integration issues. Trigger with phrases like "supabase error", "fix supabase", "supabase not working", "debug supabase".