Expert debugger for Next.js + Cloudflare Workers + Supabase stacks. Systematic troubleshooting for auth, caching, workers, RLS, CORS, and build issues. Activate on: ''debug'', ''not working'',
npx skills add https://github.com/curiositech/some_claude_skills --skill fullstack-debugger
Expert debugger for modern web stacks: Next.js 15, Cloudflare Workers, Supabase, and edge deployments. Systematic, evidence-based troubleshooting.
Activate on: "debug", "not working", "broken", "error", "500 error", "401", "403", "cache issue", "CORS error", "RLS policy", "auth not working", "blank page", "hydration error", "build failed", "worker not responding"
NOT for: Feature development → language skills | Architecture → system-architect | Performance optimization → performance-engineer
1. REPRODUCE → Can you make it fail consistently?
2. ISOLATE → Which layer is broken?
3. EVIDENCE → What do logs/network/state show?
4. HYPOTHESIZE → What could cause this?
5. TEST → Validate one hypothesis at a time
6. FIX → Minimal change that resolves issue
7. VERIFY → Confirm fix doesn't break other things
┌─────────────────────────────────────────────────────────────┐
│ DEBUGGING LAYERS │
├─────────────────────────────────────────────────────────────┤
│ │
│ Layer 1: Browser/Client │
│ ├── Console errors, network tab, React DevTools │
│ ├── localStorage/sessionStorage state │
│ └── React Query cache state │
│ │
│ Layer 2: Next.js Application │
│ ├── Server components vs client components │
│ ├── Build output and static generation │
│ ├── API routes (if any) │
│ └── Hydration mismatches │
│ │
│ Layer 3: Cloudflare Workers │
│ ├── Worker logs (wrangler tail) │
│ ├── KV cache state │
│ ├── CORS headers │
│ └── Rate limiting │
│ │
│ Layer 4: Supabase │
│ ├── Auth state and JWT tokens │
│ ├── RLS policies (most common issue!) │
│ ├── Database queries and indexes │
│ └── Realtime subscriptions │
│ │
│ Layer 5: External APIs │
│ ├── Third-party service availability │
│ ├── API rate limits │
│ └── Response format changes │
│ │
└─────────────────────────────────────────────────────────────┘
# Run from next-app/ directory
echo "=== Build Check ===" && npm run build 2>&1 | tail -20
echo "=== TypeScript ===" && npx tsc --noEmit 2>&1 | head -20
echo "=== Lint ===" && npm run lint 2>&1 | head -20
echo "=== Git Status ===" && git status --short
# Check if RLS is blocking queries (most common issue!)
node -e "
const { createClient } = require('@supabase/supabase-js');
const supabase = createClient(
'YOUR_SUPABASE_URL',
'YOUR_ANON_KEY'
);
async function diagnose() {
// Test as anonymous user
const { data, error, count } = await supabase
.from('YOUR_TABLE')
.select('*', { count: 'exact' })
.limit(5);
console.log('Error:', error);
console.log('Count:', count);
console.log('Sample:', data);
}
diagnose();
"
# Check if workers are responding
curl -s -o /dev/null -w "%{http_code}" https://YOUR-WORKER.workers.dev/health
# Check CORS headers
curl -s -D - -o /dev/null -H "Origin: https://yoursite.com" \
https://YOUR-WORKER.workers.dev/api/endpoint | grep -iE "(access-control|x-)"
# Stream worker logs
cd workers/your-worker && npx wrangler tail
# Check Cloudflare KV cache
npx wrangler kv:key list --namespace-id=YOUR_NAMESPACE_ID | head -20
# Get specific cached value
npx wrangler kv:key get --namespace-id=YOUR_NAMESPACE_ID "cache:key"
# Clear a cached item
npx wrangler kv:key delete --namespace-id=YOUR_NAMESPACE_ID "cache:key"
Symptoms:
Diagnosis:
-- In Supabase SQL Editor
-- Check what policies exist
SELECT schemaname, tablename, policyname, permissive, roles, cmd, qual
FROM pg_policies
WHERE tablename = 'your_table';
-- Test as anonymous user
SET ROLE anon;
SELECT * FROM your_table LIMIT 5;
RESET ROLE;
-- Test as authenticated user
SET ROLE authenticated;
SET request.jwt.claims = '{"sub": "user-uuid-here"}';
SELECT * FROM your_table LIMIT 5;
RESET ROLE;
Common Fixes:
-- Allow public read access
CREATE POLICY "Allow public read" ON your_table
FOR SELECT USING (true);
-- Allow authenticated users to read
CREATE POLICY "Allow authenticated read" ON your_table
FOR SELECT TO authenticated USING (true);
-- Allow users to read their own data
CREATE POLICY "Users read own data" ON your_table
FOR SELECT USING (auth.uid() = user_id);
Symptoms:
Diagnosis:
# Check what CORS headers are returned
curl -s -D - -o /dev/null \
-H "Origin: https://yoursite.com" \
-H "Access-Control-Request-Method: POST" \
-X OPTIONS \
https://your-worker.workers.dev/api/endpoint
Fix in Cloudflare Worker:
// In your worker
const corsHeaders = {
'Access-Control-Allow-Origin': '*', // Or specific domain
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
};
// Handle preflight
if (request.method === 'OPTIONS') {
return new Response(null, { headers: corsHeaders });
}
// Add to all responses
return new Response(data, {
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
});
Symptoms:
Diagnosis:
// In browser console
console.log('Session:', await supabase.auth.getSession());
console.log('User:', await supabase.auth.getUser());
console.log('LocalStorage:', Object.keys(localStorage).filter(k => k.includes('supabase')));
Common Fixes:
Symptoms:
Diagnosis:
// Temporarily add to suspect component
useEffect(() => {
console.log('Client render:', document.body.innerHTML.slice(0, 500));
}, []);
Common Fixes:
// Use client-only rendering for dynamic content
'use client';
import { useState, useEffect } from 'react';
function DynamicContent() {
const [mounted, setMounted] = useState(false);
useEffect(() => setMounted(true), []);
if (!mounted) return null; // or skeleton
return <div>{/* dynamic content */}</div>;
}
Symptoms:
Diagnosis:
# Check deployment status
npx wrangler deployments list
# View current worker code
npx wrangler deployments view
# Check for multiple environments
npx wrangler whoami
Fixes:
# Force redeploy
npx wrangler deploy --force
# Clear Cloudflare cache
curl -X POST "https://api.cloudflare.com/client/v4/zones/ZONE_ID/purge_cache" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
--data '{"purge_everything":true}'
Symptoms:
Fix:
# Nuclear option - clear all caches
rm -rf .next node_modules/.cache tsconfig.tsbuildinfo
npm run build
# Or just TypeScript cache
rm -rf node_modules/.cache/typescript
npx tsc --build --clean
Symptoms:
Diagnosis:
# Check next.config for output mode
grep -A5 "output:" next.config.ts
# Find dynamic components
grep -r "useSearchParams\|usePathname\|cookies()\|headers()" src/
Fixes:
// For components using dynamic APIs
export const dynamic = 'force-dynamic';
// or wrap in Suspense with fallback
// For generateStaticParams
export async function generateStaticParams() {
return [{ slug: 'page1' }, { slug: 'page2' }];
}
Symptoms:
Diagnosis:
# Check rate limit headers
curl -i https://your-worker.workers.dev/api/endpoint 2>&1 | grep -i ratelimit
# Check KV for rate limit keys
npx wrangler kv:key list --namespace-id=RATE_LIMIT_KV_ID | grep rate
Fixes:
# Clear rate limit for an IP
npx wrangler kv:key delete --namespace-id=RATE_LIMIT_KV_ID "rate:192.168.1.1"
# Adjust limits in wrangler.toml
RATE_LIMIT_REQUESTS = "100"
RATE_LIMIT_WINDOW = "3600"
Symptoms:
Diagnosis:
# Check cache status for a location
curl -s -D - -o /dev/null \
-H "Origin: https://yoursite.com" \
"https://your-proxy.workers.dev/api/all?lat=45.52&lng=-122.68&radius=25" \
| grep -iE "(x-cache|x-geohash|x-source)"
# Force cache refresh
curl -H "Origin: https://yoursite.com" \
"https://your-proxy.workers.dev/warm"
# Check Supabase for meeting count
node -e "
const { createClient } = require('@supabase/supabase-js');
const supabase = createClient('URL', 'KEY');
supabase.from('meetings').select('*', { count: 'exact', head: true })
.then(({count}) => console.log('Total meetings:', count));
"
Symptoms:
Diagnosis:
# Check build output locally
NODE_ENV=production npm run build 2>&1 | tee build.log
# Check for conditional imports
grep -r "require(" src/ --include="*.ts" --include="*.tsx"
# Check bundle size
npx next-bundle-analyzer
Fixes:
// next.config.ts - increase memory
module.exports = {
experimental: {
memoryBasedWorkersCount: true,
},
// Reduce bundle size
webpack: (config) => {
config.externals = [...(config.externals || []), 'sharp'];
return config;
}
};
scripts/diagnose.sh#!/bin/bash
# Run all diagnostics
echo "=== Environment ==="
node -v && npm -v
echo "=== Dependencies ==="
npm ls --depth=0 2>&1 | grep -E "(UNMET|missing)"
echo "=== TypeScript ==="
npx tsc --noEmit 2>&1 | head -30
echo "=== Build ==="
npm run build 2>&1 | tail -30
echo "=== Workers ==="
for worker in workers/*/; do
echo "Worker: $worker"
(cd "$worker" && npx wrangler whoami 2>/dev/null)
done
echo "=== Supabase ==="
npx supabase status 2>/dev/null || echo "Supabase CLI not configured"
scripts/check-rls.js// Check RLS policies are working correctly
const { createClient } = require('@supabase/supabase-js');
const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY
);
async function checkTable(table) {
console.log(`\n=== Checking ${table} ===`);
const { data, error, count } = await supabase
.from(table)
.select('*', { count: 'exact' })
.limit(1);
if (error) {
console.log(`ERROR: ${error.message}`);
} else {
console.log(`OK: ${count} rows accessible`);
}
}
// Check critical tables
['profiles', 'meetings', 'forum_posts', 'journal_entries'].forEach(checkTable);
[ ] Can reproduce the issue consistently
[ ] Identified which layer is failing (client/Next/Worker/Supabase/API)
[ ] Checked browser console for errors
[ ] Checked network tab for failed requests
[ ] Checked worker logs (wrangler tail)
[ ] Verified RLS policies allow access
[ ] Tested with fresh browser/incognito
[ ] Cleared all caches (browser, React Query, KV, TS)
[ ] Checked environment variables match production
[ ] Verified CORS headers are correct
[ ] Tested on production URL (not just localhost)
[ ] Created minimal reproduction case
When debugging, always provide:
Read, Write, Edit - File operationsBash - Run commands, curl, wranglerGrep, Glob - Search codebaseWebFetch - Test endpointsmcp__supabase__* - Direct Supabase operationsmcp__playwright__* - Browser automation for UI testingRun Python code in the cloud with serverless containers, GPUs, and autoscaling. Use when deploying ML models, running batch processing jobs, scheduling compute-intensive tasks, or serving APIs that require GPU acceleration or dynamic scaling.
Advanced GitHub Actions workflow automation with AI swarm coordination, intelligent CI/CD pipelines, and comprehensive repository management
Google Cloud Platform CLI - manage GCP resources including Compute Engine, Cloud Run, GKE, Cloud Functions, Storage, BigQuery, and more.
Expert backend architect specializing in scalable API design, microservices architecture, and distributed systems. Masters REST/GraphQL/gRPC APIs, event-driven architectures, service mesh patterns, and modern backend frameworks. Handles service boundary definition, inter-service communication, resilience patterns, and observability. Use PROACTIVELY when creating new backend services or APIs.
Run Python code in the cloud with serverless containers, GPUs, and autoscaling. Use when deploying ML models, running batch processing jobs, scheduling compute-intensive tasks, or serving APIs that require GPU acceleration or dynamic scaling.
Aspire skill covering the Aspire CLI, AppHost orchestration, service discovery, integrations, MCP server, VS Code extension, Dev Containers, GitHub Codespaces, templates, dashboard, and deployment. Use when the user asks to create, run, debug, configure, deploy, or troubleshoot an Aspire distributed application.
Audits Python + BigQuery pipelines for cost safety, idempotency, and production readiness. Returns a structured report with exact patch locations.
Microsoft Store Developer CLI (msstore) for publishing Windows applications to the Microsoft Store. Use when asked to configure Store credentials, list Store apps, check submission status, publish submissions, manage package flights, set up CI/CD for Store publishing, or integrate with Partner Center. Supports Windows App SDK/WinUI, UWP, .NET MAUI, Flutter, Electron, React Native, and PWA applications.
Take curiositech/fullstack-debugger from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.
The instructions reference npx.
Without those the skill loads but fails at the first command.