Go core idioms
Skill fusengine/agents/plugins/go-expert/skills/go-core-idioms
Redefining development through cognitive automation and collaborative agent systems.
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.
What its author says it does
Copied from the file, not written here
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.
SKILL.md
4.7 KB, 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