echolisted
Install: claude install-skill zhaojiannet/canon
This skill enforces Echo v5 conventions for Go HTTP services. Apply only when the project imports `github.com/labstack/echo/v5` (v5.0+). If the project still imports `echo/v4` or earlier, **STOP** and ask the user—v5 import path is `v5/`.
## Why Echo
Echo's selling point is its error-handling model. Handler signature `func(c *echo.Context) error` lets errors bubble naturally through the middleware chain. `*echo.HTTPError` is a typed, status-aware error that pairs cleanly with `errors.Is` / `errors.As`. A single `HTTPErrorHandler` converts every error to the wire format, so handlers stay short and uniform.
The rule: **let errors flow as errors, never as JSON written inline**. Lose this and you lose Echo's core advantage.
## Core principles
- **Handler signature**: `func(c *echo.Context) error`. Return errors. Do not write headers or JSON on the error path.
- **Use `echo.NewHTTPError(status, msg)`** for all client-facing errors. Do not call `c.JSON(http.StatusBadRequest, ...)` directly.
- **Centralize error → response in a custom `HTTPErrorHandler`**. Every handler benefits without duplication.
- **Wrap errors with `%w`** so `errors.Is` / `errors.As` still work several layers up.
- **Use sentinel errors** (`var ErrFoo = errors.New("...")`) or typed errors for business cases. Never string-compare with `err.Error()`.
- **Bind + validate every body**: `c.Bind` then `c.Validate`. Both errors propagate.
- **Use route groups for shared middleware** (auth, rate limit), not per-ro