| name | debug |
| description | Use when debugging any issue in Go, Python, or React applications — provides hands-on investigation tools including Docker inspection, API probing, log analysis, database queries, and browser debugging |
Hands-On Debugging Toolkit
Overview
This skill is the toolbox — the concrete commands and techniques for investigating bugs across the full stack. Use alongside superpowers:systematic-debugging which provides the methodology (root cause → hypothesis → test → fix).
Core principle: Observe before guessing. Every hypothesis must be backed by evidence gathered from actual system state — logs, API responses, database rows, container health, browser console.
When to Use
- Application returns unexpected responses
- Service is down or unresponsive
- Data inconsistency between layers
- Frontend shows wrong state or errors
- Docker container crashes or won't start
- Integration between services is broken
- Performance degradation in production
Phase 1: Triage — Where Is the Bug?
Before diving deep, quickly narrow down which layer is broken:
digraph triage {
"Bug reported" -> "Can you hit the API?"
"Can you hit the API?" -> "Frontend issue" [label="API works"]
"Can you hit the API?" -> "Is the container running?" [label="API fails"]
"Is the container running?" -> "Container/infra issue" [label="no"]
"Is the container running?" -> "Check API logs" [label="yes"]
"Check API logs" -> "Application bug" [label="error in logs"]
"Check API logs" -> "Check database" [label="no errors"]
"Check database" -> "Data issue" [label="bad data"]
"Check database" -> "Network/config issue" [label="data ok"]
}
Run these in parallel to triage fast:
docker compose ps
curl -s http://localhost:8000/health | jq .
docker compose logs --tail=50 api
docker compose exec postgres pg_isready -U app
Phase 2: Layer-by-Layer Investigation
Docker & Infrastructure
Container won't start:
docker compose ps -a
docker compose logs api --tail=100
lsof -i :8000
docker inspect <container_id> | jq '.[0].Config.Env'
docker inspect <container_id> | jq '.[0].Mounts'
docker inspect <container_id> | jq '.[0].NetworkSettings'
docker compose exec api sh
docker compose run --entrypoint sh api
Resource issues:
docker stats --no-stream
docker system df
docker inspect <container_id> | jq '.[0].State.OOMKilled'
Network between containers:
docker compose exec api ping postgres
docker compose exec api nc -zv postgres 5432
docker network ls
docker network inspect <network_name>
Backend API (Go/Python)
Probe endpoints directly:
curl -s http://localhost:8000/health | jq .
curl -s -X GET http://localhost:8000/api/v1/users \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" | jq .
curl -s -X POST http://localhost:8000/api/v1/users \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"email":"test@test.com","name":"Test"}' | jq .
curl -sv http://localhost:8000/api/v1/users 2>&1 | grep -E "< HTTP|< Content-Type|< X-"
curl -o /dev/null -s -w "DNS: %{time_namelookup}s\nConnect: %{time_connect}s\nTTFB: %{time_starttransfer}s\nTotal: %{time_total}s\n" http://localhost:8000/api/v1/users
Go-specific logging/debugging:
docker compose logs api 2>&1 | grep -i "error\|panic\|fatal"
curl -s http://localhost:6060/debug/pprof/goroutine?debug=2 | head -100
curl -s http://localhost:6060/debug/pprof/goroutine?debug=1 | head -5
go tool pprof http://localhost:6060/debug/pprof/heap
Python/FastAPI-specific debugging:
docker compose logs api 2>&1 | grep -E "ERROR|WARNING|Traceback"
docker compose logs api 2>&1 | grep -A 20 "Traceback"
py-spy top --pid $(pgrep uvicorn)
py-spy dump --pid $(pgrep uvicorn)
Database
Check data state:
docker compose exec postgres psql -U app -d app
psql "postgresql://app:secret@localhost:5432/app"
SELECT COUNT(*) FROM users;
SELECT * FROM users WHERE email = 'test@test.com';
SELECT u.* FROM users u
LEFT JOIN organizations o ON u.org_id = o.id
WHERE o.id IS NULL;
SELECT email, COUNT(*) FROM users GROUP BY email HAVING COUNT(*) > 1;
SELECT * FROM users ORDER BY updated_at DESC LIMIT 10;
SELECT * FROM schema_migrations;
SELECT * FROM alembic_version;
Query performance:
EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT) SELECT * FROM events WHERE user_id = $1 ORDER BY created_at DESC;
SELECT relname, pg_size_pretty(pg_total_relation_size(oid)) AS size
FROM pg_class WHERE relkind = 'r' ORDER BY pg_total_relation_size(oid) DESC LIMIT 10;
SELECT count(*), state FROM pg_stat_activity GROUP BY state;
SELECT pid, relation::regclass, mode, granted
FROM pg_locks WHERE NOT granted;
SELECT pg_cancel_backend(<pid>);
Redis debugging:
docker compose exec redis redis-cli
KEYS *
GET session:user123
TTL session:user123
TYPE session:user123
MONITOR
INFO memory
Frontend (React)
Use the browser for visual/interaction debugging. Invoke the browse skill or use Playwright MCP tools.
Browser console inspection:
Common frontend debugging scenarios:
- API call fails silently — Check network tab for failed requests, inspect response body
- State not updating — Check React Query devtools, inspect cache keys
- Blank page — Check console for errors, look for uncaught exceptions
- Wrong data displayed — Trace from API response → React Query cache → component props
- Layout broken — Take screenshot, inspect computed styles
Vite/Build issues:
bun run build 2>&1
bunx vite-bundle-visualizer
rm -rf node_modules/.vite
bun run dev
Logs Analysis Patterns
Structured log searching:
docker compose logs 2>&1 | grep -i "error\|panic\|fatal\|traceback" | tail -30
docker compose logs --since 5m api
docker compose logs -f api
docker compose logs api 2>&1 | grep "req-id-abc123"
docker compose logs api 2>&1 | grep -c "ERROR"
Phase 3: Reproduce & Isolate
Once you know which layer is broken:
- Write the exact curl/command that reproduces the bug
- Simplify — remove auth, headers, body fields until you find the minimal reproduction
- Check the boundary — is the request reaching the handler? Is the query hitting the DB?
Phase 4: Fix with Evidence
Evidence-first rule: Never claim a root cause without proof. Never claim a fix works without verification output.
Before fixing, you must have:
Then follow superpowers:systematic-debugging Phase 4:
- Write a failing test that captures the bug
- Fix the root cause (not the symptom)
- Verify the test passes — show the test output
- Check no other tests broke — show the full test run output
After fixing, report with evidence:
## Debug Report
### Status: DONE / DONE_WITH_CONCERNS
### Root Cause
[Specific explanation with file:line reference]
### Evidence
- Reproduction: `curl -X POST .../users` → 500 Internal Server Error
- Error log: `ERROR user_repo.go:45 — pq: duplicate key value violates unique constraint`
- Root cause: Missing ON CONFLICT in upsert query (user_repo.go:45)
### Fix
- Added `ON CONFLICT (email) DO UPDATE` to upsert query
- Test: `TestUpsertUser_DuplicateEmail` — PASS
- Full suite: 142/142 PASS
### Gotcha (for CLAUDE.md)
- Users table has unique constraint on email — always use upsert, not insert
Quick Reference: Debug Commands by Symptom
| Symptom | First Commands |
|---|
| Service down | docker compose ps → docker compose logs --tail=50 api |
| 500 error | curl -v endpoint → docker compose logs api | grep ERROR |
| Slow response | curl -w "Total: %{time_total}s" → EXPLAIN ANALYZE on query |
| Wrong data | psql → check actual DB rows → compare with API response |
| Auth failing | curl -v -H "Authorization: Bearer $TOKEN" → check middleware logs |
| Container OOM | docker stats → docker inspect | jq OOMKilled |
| DB connection fail | docker compose exec api nc -zv postgres 5432 → check env vars |
| Frontend blank | Browser screenshot → console messages → network requests |
| Migration stuck | SELECT * FROM schema_migrations or alembic current |
| Redis miss | redis-cli GET key → TTL key → check expiration logic |
Chains
- REQUIRED: Follow
superpowers:systematic-debugging methodology — this skill provides the tools, that skill provides the process
- REQUIRED: Report with evidence — every claim must have proof (log output, test output, curl response)
- REQUIRED: Update CLAUDE.md with discovered gotchas (
claude-md) — prevent the same bug from recurring
- Performance issues: Use
go-refactor / py-refactor after finding root cause
- Frontend issues: Use
browse skill for visual debugging with Playwright