skills/go-test-debug/SKILL.md
Debug complex Go test failures — flaky tests, race conditions, deadlocks, panics, timeouts, nil pointer dereferences. Systematic error-first diagnosis workflow.
npx skillsauth add popoffvg/dotfiles go-test-debugInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Systematic workflow for AI agents to diagnose and fix Go test failures. Optimized for token-efficient debugging — read errors first, isolate fast, fix with evidence.
Skip for simple failures - fix immediately if:
Use full workflow for:
NEVER read production code before reading error message. Reading order:
git diff for recent changesCRITICAL: If no specific test name is given, run the full package test first and save the output to a file before doing anything else. This raw output is the single most important artifact — it contains error messages, stack traces, and line numbers that guide the entire debugging process.
# When specific test is NOT known — save output for analysis
go test -v -count=1 ./package/... 2>&1 | tee /tmp/test-output.txt
# Then find failing tests from saved output
grep -E "^--- FAIL:" /tmp/test-output.txt
Once the failing test is identified, re-run it isolated:
go test -v -count=1 -run TestName ./package/...
Flags explained:
-v — show all output including t.Log-count=1 — bypass test cache (cached results show (cached) — stale data during debugging)-run — isolate the specific test; subtests use /: -run "TestFoo/case_name"For machine-parseable output when failure is complex:
go test -json -count=1 -run TestName ./package/... 2>&1 | jq 'select(.Action == "fail")'
Read the output and classify into one of these categories:
| Category | Signature in output | Jump to |
|---|---|---|
| Build error | [build failed], undefined:, cannot use | references/categories.md § Build Errors |
| Assertion failure | expected X, got Y, Not equal:, got X want Y | references/categories.md § Assertion Failures |
| Panic / nil pointer | panic:, nil pointer dereference, stack trace | references/categories.md § Panics |
| Race condition | WARNING: DATA RACE | references/categories.md § Race Conditions |
| Timeout / deadlock | test timed out, all goroutines are asleep | references/categories.md § Timeouts |
| Flaky test | Passes sometimes, fails other times | references/categories.md § Flaky Tests |
| Environment / fixtures | no such file, connection refused, env var missing | references/categories.md § Environment Issues |
Run checks in order:
go build ./... — does it compile?go vet ./... — static analysis issues?go test -v -count=1 -run TestSpecific ./package/... — specific testgo test -race -count=1 ./package/... — race conditions?Check what changed recently — the bug is almost always in the diff:
git diff HEAD~3 -- ./package/
git log --oneline -5 -- ./package/
go test -v -run TestFoo ./package/... # see all subtests
go test -v -run "TestFoo/failing_case" ./package/... # isolate one case
Spaces in subtest names become _ in the regex. Find the case struct in test code by matching the name field.
Before debugging logic, verify the test isn't failing due to environment:
TestMain(m *testing.M) setup/teardowntestdata/ directory for required fixturesos.Getenv / os.LookupEnv in test files//go:build integrationlocalhost:5432, :6379, etc.result, _ := Func().sync.Mutex, channels, atomic). Never use time.Sleep().WaitGroup counts, mutex ordering.# Verify the fix
go test -v -count=1 -run TestName ./package/...
# Run broader to catch regressions
go test -count=1 ./package/...
# Race check
go test -race -count=1 ./package/...
t.Logf()t.Logf() for temporary debug output — it only prints on failure or with -v, and stays cleant.Logf() doesn't give enough visibilitygo-debug skill for Delve workflowsfmt.Println in tests — use t.Logf() insteadTest failed
├── Doesn't compile? → go build ./... → fix compilation
├── Read error message → classify type:
│ ├── "expected X, got Y" → read test inputs → read function → check diff → fix code
│ ├── "panic:" → read stack trace top frame → go to file:line → find nil pointer → trace back
│ ├── "DATA RACE" → note two locations → identify shared var → add sync primitive
│ ├── "test timed out" → check goroutine states → find blocked chan/mutex → fix
│ ├── "no such file" / "connection refused" → check fixtures/env/TestMain
│ └── Intermittent → go test -count=100 -failfast → find non-determinism source
└── After fix: go test -v -count=1 + go test -race
# Essential debugging commands
go test -v -count=1 -run TestName ./pkg/... # isolated, no cache
go test -race -count=1 ./pkg/... # race detector
go test -count=100 -failfast -run TestX ./pkg/... # reproduce flaky
For detailed diagnosis per failure type, see references/categories.md
Eval checklist:
Test inputs:
Can change: diagnosis workflow steps, file reading order, isolation strategies, evidence gathering Cannot change: error-first principle (read errors before code), evidence-driven requirement Min sessions before eval: 5 Runs per experiment: 3
tools
Improve a whole CLAUDE.local.md — the private, per-project rules captured from user corrections. Wraps each conditional rule in a <task-relevant> block so it only surfaces for matching work, merges duplicates, generalizes one-off facts, drops stale entries, and routes raw project facts to engram. Use when the user says "improve claude.local", "clean up the local rules", "claude.local is bloated", or after the Stop hook has appended many rules.
testing
WM pipeline and conventions shared across all phases. Agents must read this before spec, impl, or verify work.
development
One entry point for spec writing, implementation, and bug fixing. Default is new (write spec → grill loop → produce notes → author TODO bodies). Other subcommands: verify (audit), revise (sync to shipped), prototype (settle a decision), code-map (diagram), impl (execute one TODO), fix (analyze cause, correct thoughts, fix behavior), help (this page). Invoke as /code <subcommand>.
development
Red-Green-Refactor cycle for bug fixes. Before fixing a bug, first write a failing test that reproduces it (Red), then make the minimal change to pass (Green), then clean up the code (Refactor). Use on any bug fix, error correction, failing test repair, or when user says "fix this bug".