Go core idioms
Skill fusengine/agents/plugins/go-expert/skills/go-core-idioms
Use when: writing or reviewing idiomatic sequential Go — error handling (%w wrapping, errors.Join, errors.Is/As, errors.AsType), slog structured logging, generics, small consumer-side interfaces, naming/style, new(expr), go fix modernizers. Do NOT use for: goroutines/channels/errgroup/context concurrency (use go-concurrency), non-Go languages, framework-specific code.From its SKILL.md
npx -y skills add fusengine/agents --skill go-core-idiomsAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 22 stars22 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
4.7 KB, ~1.1k tokens by cl100k_base, as published. Nobody here has run it
Go Core Idioms
Idiomatic sequential Go for 1.26. For anything touching goroutines, channels,
errgroup, or context cancellation, use go-concurrency instead.
Agent Workflow (MANDATORY)
Before ANY implementation, use TeamCreate to spawn 3 agents:
- fuse-ai-pilot:explore-codebase - Map existing error/logging/interface patterns
- fuse-ai-pilot:research-expert - Verify latest Go docs via Context7/Exa
- mcp__context7__query-docs - Confirm stdlib signatures (errors, log/slog)
After implementation, run fuse-ai-pilot:sniper for validation.
Overview
| Feature | Description |
|---|---|
| Error handling | Explicit if err != nil, %w wrapping, errors.Join, errors.AsType (1.26) |
| Structured logging | log/slog stdlib — handlers, attrs, groups, LogValuer |
| Generics | Type params, constraints, self-referential types (1.26) |
| Interfaces | Small, consumer-side — "accept interfaces, return structs" |
| Modernizers | go fix auto-applies dozens of idiom/API fixers (1.26) |
Critical Rules
- Explicit
if err != nil- No sugar exists; never discard with_ = err - Wrap with
%w, not%v- Preserves the chain forerrors.Is/As/AsType - Accept interfaces, return structs - Define interfaces where consumed, not where produced
- Value receivers by default - Use pointer receivers only for mutation or large structs
- Run
go fix+go vet- Let modernizers migrate to current idioms (1.26)
Architecture
internal/
├── user/
│ ├── user.go # struct + value-receiver methods
│ ├── errors.go # sentinel + typed errors
│ └── repository.go # consumer-side interface, concrete struct returned
└── platform/
└── logging/
└── logger.go # slog setup, one *slog.Logger injected downward
→ See error-patterns.md for full example
Reference Guide
Concepts
| Topic | Reference | When to Consult |
|---|---|---|
| Error handling | error-handling.md | Wrapping, sentinels, errors.Join, AsType |
| Structured logging | slog-logging.md | Choosing handlers, attrs, groups, perf |
| Generics & 1.26 | generics-and-1.26.md | Type params, self-ref types, new(expr) |
| Interfaces & style | interfaces-and-style.md | Interface placement, naming, receivers |
Templates
| Template | When to Use |
|---|---|
| error-patterns.md | Building an error strategy for a package |
| slog-setup.md | Wiring a structured logger into an app |
Quick Reference
Wrap and inspect errors
if err != nil {
return fmt.Errorf("load user %d: %w", id, err) // %w keeps the chain
}
// 1.26: type-safe, generic replacement for errors.As
if pathErr, ok := errors.AsType[*fs.PathError](err); ok {
log.Printf("failed path: %s", pathErr.Path)
}
→ See error-handling.md
Structured logging with slog
logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
logger.Info("user created", "id", id, slog.Duration("took", elapsed))
→ See slog-logging.md
Best Practices
DO
- Keep interfaces one-to-three methods, named at the call site
- Add context on the way up with
%w; check witherrors.Is/AsType - Use
slog.LogAttrson hot paths to avoid allocation - Run
go fixto adopt current APIs and idioms automatically (1.26)
DON'T
- Swallow errors (
_ = err) or return bareerrwhen context helps - Define interfaces next to their implementation "just in case"
- Reach for pointer receivers without a mutation or size reason
- Write Java-esque getters/setters or
IFoointerface prefixes
What ships with it: 7 files
16.4 KB alongside SKILL.md
references/
- error-handling.md3.0 KB
- generics-and-1.26.md2.8 KB
- interfaces-and-style.md3.1 KB
- slog-logging.md3.2 KB
- templates/error-patterns.md2.2 KB
- templates/slog-setup.md2.2 KB
- .gitkeep0 B