skills/golang-patterns/SKILL.md
Use this skill when implementing or reviewing Go code that needs idiomatic concurrency, error handling, interface design, package structure, service patterns, readability, correctness, or maintainability.
npx skillsauth add chatandbuild/skills-repo Golang PatternsInstall 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.
Apply idiomatic Go patterns that keep code explicit, testable, and production-safe.
Error wrapping: Use fmt.Errorf("context: %w", err) to wrap errors and preserve the chain. Use errors.Is and errors.As for unwrapping.
if err != nil {
return fmt.Errorf("fetch user %s: %w", id, err)
}
if errors.Is(err, ErrNotFound) { /* handle */ }
Sentinel errors: Define package-level var ErrX = errors.New("x") for expected conditions. Use errors.Is for checks.
Context patterns: Use context.WithCancel when you need to signal stop; use context.WithTimeout or context.WithDeadline for bounded work. Always pass context as first parameter.
ctx, cancel := context.WithTimeout(parent, 5*time.Second)
defer cancel()
result, err := doWork(ctx)
sync.WaitGroup and errgroup: Use errgroup.Group when you need to run goroutines and collect the first error. Use WaitGroup for fire-and-forget parallelism with explicit sync.
g, ctx := errgroup.WithContext(ctx)
g.Go(func() error { return fetchA(ctx) })
g.Go(func() error { return fetchB(ctx) })
if err := g.Wait(); err != nil { return err }
Table-driven tests: Structure tests as a slice of cases with inputs and expected outputs. Loop over cases and run subtests.
for _, tc := range []struct{ name string; input int; want int }{
{"zero", 0, 0}, {"positive", 1, 1},
} {
t.Run(tc.name, func(t *testing.T) {
if got := fn(tc.input); got != tc.want { t.Errorf("got %d", got) }
})
}
Interface segregation at call site: Define interfaces where they are used, with only the methods needed. Avoid large shared interfaces.
Worker pool: Use a buffered channel as a job queue; spawn N workers that read from the channel. Close the channel when done; workers exit when channel is closed.
Fan-out/fan-in: Start multiple goroutines that produce into a channel; one goroutine (or a merge function) reads from all and aggregates. Use sync.WaitGroup to know when producers are done.
Channel select with timeout: Use select with <-time.After(d) or <-ctx.Done() to avoid blocking forever.
select {
case result := <-ch:
return result, nil
case <-ctx.Done():
return nil, ctx.Err()
case <-time.After(10 * time.Second):
return nil, ErrTimeout
}
context or a done channel.sync.Mutex or channels.defer in a loop defers until the enclosing function returns, not each iteration. Use an explicit function call or wrap in a closure.init(). Makes testing and reasoning harder. Prefer explicit setup.## Pattern Choices and Rationale
- <pattern>: <why it fits>
## Before/After Architecture
- <structural changes>
- <ownership boundaries>
## Error and Concurrency Guarantees
- Error wrapping: <locations and chain>
- Context propagation: <boundaries>
- Goroutine lifecycle: <start, stop, leak check>
## Concurrency Pattern Applied
- <worker pool | fan-out/fan-in | select timeout | other>
- Code sketch: <snippet if applicable>
## Pitfall Check
- Goroutine leaks: <assessment>
- Shared state: <mutex/channel usage>
- defer/init: <issues if any>
## Test Additions
- Table-driven cases: <coverage>
- Race detector: <recommendation>
## Residual Risks
- <remaining concerns>
tools
Use only when the user explicitly asks to stage, commit, push, and open a GitHub pull request in one flow using the GitHub CLI (`gh`).
development
Use this skill any time a spreadsheet file is the primary input or output. This means any task where the user wants to: open, read, edit, or fix an existing .xlsx, .xlsm, .csv, or .tsv file (e.g., adding columns, computing formulas, formatting, charting, cleaning messy data); create a new spreadsheet from scratch or from other data sources; or convert between tabular file formats. Trigger especially when the user references a spreadsheet file by name or path — even casually (like "the xlsx in my downloads") — and wants something done to it or produced from it. Also trigger for cleaning or restructuring messy tabular data files (malformed rows, misplaced headers, junk data) into proper spreadsheets. The deliverable must be a spreadsheet file. Do NOT trigger when the primary deliverable is a Word document, HTML report, standalone Python script, database pipeline, or Google Sheets API integration, even if tabular data is involved.
development
Use this skill when turning messy workout information into clear logs, comparing user-provided sessions, surfacing trends or likely PRs, and suggesting realistic next-session steps.
tools
Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.