
debugging
by Mavrick91
SKILL.md
name: debugging description: Debug common issues with authentication, payments, database queries, React components, and API routes. Use when troubleshooting errors, investigating bugs, or diagnosing unexpected behavior.
Debugging Guide
Solutions for common issues in this application.
Quick Diagnosis
| Symptom | Likely Cause | Check |
|---|---|---|
| 401 Unauthorized | Session expired/missing | Cookie presence, session expiry |
| 403 Forbidden | Wrong role | User role in database |
| 429 Too Many Requests | Rate limited | Wait for retry-after |
| 500 Server Error | Unhandled exception | Server logs |
| Empty response | Query returned nothing | Database data |
| Stale data | Cache not invalidated | React Query cache |
| Form not submitting | Validation error | Console, field errors |
Authentication Issues
"Unauthorized" (401)
Check session cookie:
// In browser DevTools > Application > Cookies
// Look for 'session' cookie
// Or in API route:
const cookie = request.headers.get('cookie')
console.log('Cookie header:', cookie)
Check session in database:
SELECT * FROM sessions WHERE id = 'session-id-from-cookie';
-- Check expires_at is in the future
Common fixes:
- Clear cookies and re-login
- Check cookie domain matches
- Verify
credentials: 'include'in fetch calls
"Forbidden" (403)
Check user role:
SELECT id, email, role FROM users WHERE id = 'user-id';
-- Should be 'admin' for admin routes
Fix:
UPDATE users SET role = 'admin' WHERE email = 'admin@example.com';
Login Not Working
Check password hash:
import { verify } from 'bcrypt-ts'
const isValid = await verify(inputPassword, user.passwordHash)
console.log('Password valid:', isValid)
Common issues:
- Password not meeting requirements (8+ chars, uppercase, lowercase, number)
- Rate limited (5 attempts per 15 minutes)
- Wrong email (check exact match, case-sensitive)
Database Issues
Query Returns Empty
Check data exists:
SELECT * FROM products WHERE id = 'product-id';
SELECT * FROM products WHERE handle = 'product-handle';
Check query conditions:
// Add logging
console.log('Query params:', { search, status, page })
const results = await db.select().from(products).where(whereClause)
console.log('Results:', results.length)
N+1 Query Performance
Symptom: Slow API responses, many database queries
Diagnose:
// Add query logging in db/index.ts
const db = drizzle(pool, {
logger: true, // Logs all queries
})
Fix: Use batch queries with Maps (see database skill)
Migration Fails
Check migration status:
yarn db:studio # Open Drizzle Studio
Reset and retry:
# Development only!
yarn db:push # Push schema directly
Check for conflicts:
-- Check existing tables/columns
SELECT column_name, data_type
FROM information_schema.columns
WHERE table_name = 'your_table';
API Route Issues
Request Body Empty
Check Content-Type:
console.log('Content-Type:', request.headers.get('content-type'))
// Must be application/json for JSON body
const body = await request.json()
console.log('Body:', body)
Fix frontend:
fetch('/api/resource', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
credentials: 'include',
})
CORS Errors
Symptom: "CORS policy" error in browser console
Check:
- API route exists at correct path
- Request method matches handler
- Credentials included if needed
Rate Limiting
Symptom: 429 Too Many Requests
Check Retry-After header:
const response = await fetch('/api/auth/login', { ... })
if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After')
console.log('Wait seconds:', retryAfter)
}
Tiers:
auth: 5 requests per 15 minutesapi: 100 requests per minutewebhook: 50 requests per minute
Payment Issues
Stripe Payment Fails
Check PaymentIntent status:
const paymentIntent = await stripe.paymentIntents.retrieve(paymentIntentId)
console.log('Status:', paymentIntent.status)
console.log('Last error:', paymentIntent.last_payment_error)
Common issues:
- Test card declined (use 4242 4242 4242 4242)
- Amount too low (minimum varies by currency)
- Missing required fields
Webhook Not Received
Check webhook configuration:
- Stripe Dashboard > Developers > Webhooks
- Verify endpoint URL is correct
- Check webhook secret matches env var
Test locally with Stripe CLI:
stripe listen --forward-to localhost:3000/api/webhooks/stripe
Check signature:
try {
const event = stripe.webhooks.constructEvent(body, sig, secret)
} catch (err) {
console.error('Webhook signature failed:', err.message)
}
Checkout Expired
Check expiration:
SELECT id, expires_at, completed_at
FROM checkouts
WHERE id = 'checkout-id';
Extend expiration (dev only):
UPDATE checkouts
SET expires_at = NOW() + INTERVAL '24 hours'
WHERE id = 'checkout-id';
React/Frontend Issues
Component Not Updating
Check React Query cache:
// Force refetch
const queryClient = useQueryClient()
queryClient.invalidateQueries({ queryKey: ['products'] })
Check Zustand state:
// In browser DevTools console
const state = useCartStore.getState()
console.log('Cart items:', state.items)
Form Validation Not Working
Check field configuration:
{
name: 'email',
type: 'email',
label: 'Email',
required: true, // Must be true for validation
validate: (value) => {
console.log('Validating:', value) // Debug
if (!value) return 'Required'
},
}
Check form ref:
const formRef = useRef<FNFormRef | null>(null)
// Is ref connected?
console.log('Form ref:', formRef.current)
// Try manual submit
formRef.current?.submit()
Hydration Mismatch
Symptom: "Text content does not match" warning
Common causes:
- Date/time formatting (server vs client timezone)
- Random values (use seeded random or useId)
- LocalStorage access during SSR
Fix:
// Use useEffect for client-only values
const [mounted, setMounted] = useState(false)
useEffect(() => setMounted(true), [])
if (!mounted) return <Skeleton />
return <ClientOnlyComponent />
i18n Missing Key
Symptom: Shows key instead of translation
Check:
- Key exists in all locale files
- i18n initialized before render
- Correct namespace
Debug:
const { t, i18n } = useTranslation()
console.log('Current lang:', i18n.language)
console.log('Translation:', t('key', { returnDetails: true }))
Logging & Monitoring
Add Request Logging
// In API route
import { logRequest, createRequestTimer } from '@/lib/logger'
GET: async ({ request }) => {
const timer = createRequestTimer()
try {
// ... handler logic
logRequest(request, response, timer)
return response
} catch (error) {
logError('Handler failed', error, { url: request.url })
throw error
}
}
Debug Database Queries
// Temporarily enable query logging
import { drizzle } from 'drizzle-orm/node-postgres'
const db = drizzle(pool, {
logger: {
logQuery(query, params) {
console.log('Query:', query)
console.log('Params:', params)
},
},
})
Common Error Messages
| Error | Meaning | Fix |
|---|---|---|
ECONNREFUSED | Database not running | Start PostgreSQL |
relation does not exist | Table missing | Run migrations |
duplicate key value | Unique constraint | Check for existing record |
invalid input syntax for type uuid | Bad UUID format | Validate UUID before query |
JWT expired | Token expired | Refresh token or re-auth |
rate limit exceeded | Too many requests | Wait and retry |
Environment Issues
Missing Environment Variable
// Check at startup
const required = ['DATABASE_URL', 'STRIPE_SECRET_KEY', 'CHECKOUT_SECRET']
for (const key of required) {
if (!process.env[key]) {
throw new Error(`Missing required env var: ${key}`)
}
}
Wrong Environment
// Check which environment
console.log('NODE_ENV:', process.env.NODE_ENV)
console.log('Is production:', process.env.NODE_ENV === 'production')
Useful Commands
# Check database connection
yarn db:studio
# Run single test with logging
yarn vitest run path/to/test.ts --reporter=verbose
# Type check
yarn typecheck
# Check for lint errors
yarn lint
# View build output
yarn build && ls -la .output/
See Also
api-routesskill - API debugging patternsdatabaseskill - Query debuggingcheckoutskill - Payment debuggingtestingskill - Test debuggingsecurityskill - Auth debugging
Score
Total Score
Based on repository quality metrics
SKILL.mdファイルが含まれている
ライセンスが設定されている
100文字以上の説明がある
GitHub Stars 100以上
3ヶ月以内に更新がある
10回以上フォークされている
オープンIssueが50未満
プログラミング言語が設定されている
1つ以上のタグが設定されている
Reviews
Reviews coming soon