go-safety

Enforces defensive Go coding practices for error handling, nil safety, and numeric edge cases.

1|2|Updated Nov 25, 2017
One-click install
npx skills add https://github.com/asarchami/dotfiles --skill go-safety-asarchami
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: go-safety
Source: https://github.com/asarchami/dotfiles/tree/main/dot_config/opencode/skills/go/go-safety
Command: npx skills add https://github.com/asarchami/dotfiles --skill go-safety-asarchami

SYSTEM DOCUMENTATION & REQUIREMENTS

💡 This Skill includes references (resource) components.

What problem does it solve? Go code often ships with subtle runtime bugs: swallowed errors, nil map panics, typed-nil interface traps, silent integer truncation, and shared slice backing arrays. This Skill provides a systematic checklist and deep references to write and review Go code that handles errors correctly and guards every nil, pointer, slice, and numeric edge. ## Core Features & Use Cases - Error Handling Discipline: Enforces checking and wrapping every error with %w, inspecting with errors.Is/errors.As/errors.Join, and applying the single handling rule (log XOR return) with a clear panic policy. - Defensive Coding Guards: Covers comma-ok type assertions, nil map initialization, append backing-array traps, defensive copying with slices.Clone/maps.Clone, integer bounds checks, float epsilon comparison, and safe zero-value design. - Use Case: When reviewing a Go pull request, activate this Skill to audit the diff for discarded errors, log-and-return duplicates, bare type assertions, and unguarded numeric conversions before merge. ## Quick Start Review this Go diff for error handling mistakes, nil safety issues, and numeric pitfalls using the go-safety guidelines.

Frequently Asked Questions about go-safety

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I handle errors correctly in Go?

Check every returned error, wrap it with context using fmt.Errorf and the %w verb, and inspect chains with errors.Is and errors.As instead of direct comparison. Each error must be either logged or returned, never both, and panics are reserved for violated invariants only.

What is the difference between %w and %v in Go error wrapping?

The %w verb preserves the error chain so callers can unwrap it with errors.Is and errors.As, while %v only formats the message and breaks the chain. Use %w internally and %v at public API or system boundaries to hide internal error types.

Why does my Go function return a non-nil error when it returns nil?

This is the typed-nil interface trap: returning a typed nil pointer as an error interface produces a non-nil interface because the type descriptor is set. Fix it by returning the untyped nil literal explicitly instead of a typed nil variable.

How do I safely copy slices and maps in Go?

Use slices.Clone and maps.Clone from the Go 1.21+ standard library for defensive copies so callers cannot mutate internal state. To force append to allocate a new backing array, use the full slice expression s[:len(s):len(s)].

When should I use panic instead of returning an error in Go?

Panic only for programmer errors, impossible conditions, or violated invariants, such as Must* functions at init time. Expected failures like network errors or invalid input must be returned as errors, and recover should only appear at goroutine boundaries.

Why does comparing floats with == fail in Go?

Float arithmetic is not exact, so direct equality comparison produces unexpected results due to rounding. Compare using an epsilon threshold such as math.Abs(a-b) < epsilon, or use math/big for exact decimal arithmetic.