mir-backend-go-echolisted
Install: claude install-skill anantbhandarkar/make-it-right
# /mir-backend-go-echo · Make It Right (Echo)
Bottom tier of the chain: `mir-backend` (generic gates) → `mir-backend-go` (Go runtime model) → **this** (Echo library mechanics). Run the gates first; load the Go runtime tier for goroutine lifecycle, context propagation, and race discipline; reach for *this* at Gate 5 (design mechanics), Gate 6 (implementation), and Gate 7 review. **Runtime-level concerns (goroutine leaks, data races, context propagation, typed-nil, slice aliasing) live in `mir-backend-go` — not here.**
**Stack assumed:** `github.com/labstack/echo/v4`. Notes apply to Echo v4; v5 (pre-release) has a different context model.
## The Echo footguns AI walks into most
### 1. `echo.Context` is request-scoped — do not retain it across the handler boundary
Echo creates one `echo.Context` per request. The underlying `net/http` request and response objects are replaced per request, and some Echo versions pool the context. Storing `echo.Context` in a struct or passing it to a goroutine and reading it after the handler returns results in a data race — you read the next request's data or a zeroed struct.
- Extract specific values before spawning any goroutine and pass those values (plain strings, ints, typed structs) instead of the context:
```go
// WRONG: c is reused/zeroed after the handler returns
func handler(c echo.Context) error {
go func() {
sendNotification(c.Param("id"), c.Request().Header.Get("X-Trace-Id"))
}()
return c.NoCont