labstack/echo · critical
panic: err from g.AddRoute in Group.Add
Error message
panic: err from g.AddRoute in Group.Add
What it means
Panicked inside Group.Add (group.go:198) when g.AddRoute returns an error for the single route being added. Group.Add wraps one method+path+handler registration and panics on any router error (invalid path, conflicting params, duplicate route). This is the v4 convention; v5 returns the error.
Source
Thrown at group.go:198
}
// RouteNotFound implements `Echo#RouteNotFound()` for sub-routes within the Group.
//
// Example: `g.RouteNotFound("/*", func(c *echo.Context) error { return c.NoContent(http.StatusNotFound) })`
func (g *Group) RouteNotFound(path string, h HandlerFunc, m ...MiddlewareFunc) RouteInfo {
return g.Add(RouteNotFound, path, h, m...)
}
// Add implements `Echo#Add()` for sub-routes within the Group. Panics on error.
func (g *Group) Add(method, path string, handler HandlerFunc, middleware ...MiddlewareFunc) RouteInfo {
ri, err := g.AddRoute(Route{
Method: method,
Path: path,
Handler: handler,
Middlewares: middleware,
})
if err != nil {
panic(err) // this is how `v4` handles errors. `v5` has methods to have panic-free usage
}
return ri
}
// AddRoute registers a new Routable with Router
func (g *Group) AddRoute(route Route) (RouteInfo, error) {
// Combine middleware into a new slice to avoid accidentally passing the same slice for
// multiple routes, which would lead to later add() calls overwriting the
// middleware from earlier calls.
groupRoute := route.WithPrefix(g.prefix, append([]MiddlewareFunc{}, g.middleware...))
return g.echo.add(groupRoute)
}
View on GitHub (pinned to 05489dc173)
Solutions
- Read the wrapped error from AddRoute to find the exact router rejection reason.
- Remove duplicate registrations for the same method+path.
- Keep parameter names consistent at each path segment across all routes.
- Use echo.Config{...} or distinct prefixes to avoid cross-group collisions.
Example fix
// before
g.GET("/users/:id", h1)
g.GET("/users/:id", h2) // duplicate -> panic
// after
g.GET("/users/:id", h1)
g.GET("/users/:id/edit", h2) Defensive patterns
Strategy: validation
Validate before calling
// Wrap a single Add in a recover to convert the panic into an error for diagnostics.
func addSafe(g *echo.Group, method, path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) (err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("Group.Add %s %s: %v", method, path, r)
}
}()
g.Add(method, path, h, m...)
return nil
} Prevention
- Avoid duplicate method+path registrations across groups.
- Keep param/wildcard names consistent at each path segment.
- Validate paths for unsupported characters before registering.
When it happens
Trigger: Calling g.Add(method, path, handler) (or convenience methods g.GET, g.POST, etc.) with a path the router rejects: invalid parameter syntax, conflicting wildcard/param at the same position, or a duplicate route registration.
Common situations: Duplicate route registration; mixing ':param' and '*wildcard' at the same path segment; invalid characters in the path; registering the same method+path twice across groups.
Related errors
- panic: errs collected from g.AddRoute failures in Group.Matc
- panic: err from g.AddRoute(Route{Method: RouteNotFound, Path
- echo basic-auth middleware requires a validator function
- echo body-dump middleware requires a handler function
- invalid gzip level
AI-assisted analysis of labstack/echo@05489dc173 (2026-08-04).
Data as JSON: /data/errors/91707d37093260e9.json.
Report an issue: GitHub.