labstack/echo · critical

panic: errs collected from g.AddRoute failures in Group.Matc

Error message

panic: errs collected from g.AddRoute failures in Group.Match

What it means

Panicked inside Group.Match (group.go:125) after collecting errors from one or more g.AddRoute calls across the requested HTTP methods. Match registers the same path for multiple methods; any AddRoute failures are accumulated in an errs slice, and if non-empty, the whole slice is panicked. This is v4's error model — v5 returns errors instead.

Source

Thrown at group.go:125

// Match implements `Echo#Match()` for sub-routes within the Group. Panics on error.
func (g *Group) Match(methods []string, path string, handler HandlerFunc, middleware ...MiddlewareFunc) Routes {
	errs := make([]error, 0)
	ris := make(Routes, 0)
	for _, m := range methods {
		ri, err := g.AddRoute(Route{
			Method:      m,
			Path:        path,
			Handler:     handler,
			Middlewares: middleware,
		})
		if err != nil {
			errs = append(errs, err)
			continue
		}
		ris = append(ris, ri)
	}
	if len(errs) > 0 {
		panic(errs) // this is how `v4` handles errors. `v5` has methods to have panic-free usage
	}
	return ris
}

// Group creates a new sub-group with prefix and optional sub-group-level middleware.
//
// Important! Group middlewares are executed in case there was no exact route match as by default Group registers
// `/*` NotFound routes for itself. If this kind of behavior is not needed, then create an Echo instance with the ` noAutoRegisterRoutes `
// flag set to true. Example `echo.NewWithConfig(echo.Config{NoGroupAutoRegister404Routes: true})`.
func (g *Group) Group(prefix string, middleware ...MiddlewareFunc) (sg *Group) {
	m := make([]MiddlewareFunc, 0, len(g.middleware)+len(middleware))
	m = append(m, g.middleware...)
	m = append(m, middleware...)
	sg = g.echo.Group(g.prefix+prefix, m...)
	return
}

// Static implements `Echo#Static()` for sub-routes within the Group.

View on GitHub (pinned to 05489dc173)

Solutions

  1. Inspect the panicked []error slice to see exactly which method/path failed.
  2. Ensure consistent parameter names for the same path across all methods in the Match call.
  3. Resolve route conflicts (duplicate registrations, static-vs-param collisions) before calling Match.
  4. Register methods individually with g.Add to isolate which registration fails.

Example fix

// before: inconsistent param names cause conflict
g.Match([]string{"GET","POST"}, "/users/:userId", h) // elsewhere /users/:id exists
// after: use consistent param names everywhere
g.Match([]string{"GET","POST"}, "/users/:id", h)
Defensive patterns

Strategy: validation

Validate before calling

// Register methods individually and collect errors instead of letting Match panic.
func matchSafe(g *echo.Group, methods []string, path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) (err error) {
    for _, meth := range methods {
        // echo v4 Add panics; wrap in recover to capture the error.
        func() {
            defer func() {
                if r := recover(); r != nil {
                    err = fmt.Errorf("register %s %s: %v", meth, path, r)
                }
            }()
            g.Add(meth, path, h, m...)
        }()
        if err != nil { return }
    }
    return nil
}

Prevention

When it happens

Trigger: Calling g.Match([]string{"GET","POST"}, path, h) where one or more method+path combinations conflict with already-registered routes or are rejected by the router (invalid path syntax, conflicting param names, duplicate static+param overlap).

Common situations: Registering a path with mismatched parameter names across methods; path syntax errors (e.g. ':id' vs '*id'); route conflicts where a static path shadows a parameter route; typos in HTTP method names.

Related errors


AI-assisted analysis of labstack/echo@05489dc173 (2026-08-04). Data as JSON: /data/errors/50e5a2bb4891bfd0.json. Report an issue: GitHub.