{"id":"91707d37093260e9","repo":"labstack/echo","slug":"panic-err-from-g-addroute-in-group-add","errorCode":null,"errorMessage":"panic: err from g.AddRoute in Group.Add","messagePattern":"panic: err from g\\.AddRoute in Group\\.Add","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"group.go","lineNumber":198,"sourceCode":"}\n\n// RouteNotFound implements `Echo#RouteNotFound()` for sub-routes within the Group.\n//\n// Example: `g.RouteNotFound(\"/*\", func(c *echo.Context) error { return c.NoContent(http.StatusNotFound) })`\nfunc (g *Group) RouteNotFound(path string, h HandlerFunc, m ...MiddlewareFunc) RouteInfo {\n\treturn g.Add(RouteNotFound, path, h, m...)\n}\n\n// Add implements `Echo#Add()` for sub-routes within the Group. Panics on error.\nfunc (g *Group) Add(method, path string, handler HandlerFunc, middleware ...MiddlewareFunc) RouteInfo {\n\tri, err := g.AddRoute(Route{\n\t\tMethod:      method,\n\t\tPath:        path,\n\t\tHandler:     handler,\n\t\tMiddlewares: middleware,\n\t})\n\tif err != nil {\n\t\tpanic(err) // this is how `v4` handles errors. `v5` has methods to have panic-free usage\n\t}\n\treturn ri\n}\n\n// AddRoute registers a new Routable with Router\nfunc (g *Group) AddRoute(route Route) (RouteInfo, error) {\n\t// Combine middleware into a new slice to avoid accidentally passing the same slice for\n\t// multiple routes, which would lead to later add() calls overwriting the\n\t// middleware from earlier calls.\n\tgroupRoute := route.WithPrefix(g.prefix, append([]MiddlewareFunc{}, g.middleware...))\n\treturn g.echo.add(groupRoute)\n}\n","sourceCodeStart":180,"sourceCodeEnd":211,"githubUrl":"https://github.com/labstack/echo/blob/05489dc1730161df26b72d1ae2a3ba6fb8178fc7/group.go#L180-L211","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\ng.GET(\"/users/:id\", h1)\ng.GET(\"/users/:id\", h2) // duplicate -> panic\n// after\ng.GET(\"/users/:id\", h1)\ng.GET(\"/users/:id/edit\", h2)","handlingStrategy":"validation","validationCode":"// Wrap a single Add in a recover to convert the panic into an error for diagnostics.\nfunc addSafe(g *echo.Group, method, path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) (err error) {\n    defer func() {\n        if r := recover(); r != nil {\n            err = fmt.Errorf(\"Group.Add %s %s: %v\", method, path, r)\n        }\n    }()\n    g.Add(method, path, h, m...)\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Avoid duplicate method+path registrations across groups.","Keep param/wildcard names consistent at each path segment.","Validate paths for unsupported characters before registering."],"tags":["group","router","panic","startup","routing"],"analyzedSha":"05489dc1730161df26b72d1ae2a3ba6fb8178fc7","analyzedAt":"2026-08-04T21:32:47.783Z","schemaVersion":2}