Skip to content

Group routes does not work without leading slash #3099

Description

@sayeed1999

Group route does not work without leading slash

I ran into an unexpected behavior with grouped routes.

g := e.Group("/v1")
g.GET("posts", handler)

Requesting:

GET /v1/posts

returns:

Not Found

Changing it to:

g.GET("/posts", handler)

works as expected.

I would expect Echo to handle the missing leading / when combining the group prefix and route path, or at least provide a warning during route registration.

It would be nice if both forms resulted in /v1/posts:

g.GET("posts", handler)
g.GET("/posts", handler)

Because it is very normal for a developer to not provide the slash since a group already means it's under that group (so slash should come automatically)

Otherwise its too confusing and something to forget easily when using the framework!!

Activity

  1. sayeed1999 commented on Sep 22, 2026

    @sayeed1999
    Author

    @aldas why group prefix doesn't need to mean sub-groups you are commenting on the unmerged PRs? I think most programmers use groups in their projects to group routes.

  2. aldas commented on Sep 22, 2026

    @aldas
    Contributor

    because this works today and has been for a long time. Changing how it works would be breaking change. And yes - inside group we register 404 routes with slashes, but this is because we have done ad-hoc "fixes" in past, to things we actually have not defined what they actually are and how should they behave.

    Currently this works:

    package main
    
    import (
    	"log/slog"
    	"net/http"
    
    	"github.com/labstack/echo/v5"
    )
    
    func main() {
    
    	e := echo.New()
    
    	g := e.Group("prefix")
    	g.GET("-1", func(c *echo.Context) error {
    		return c.String(http.StatusOK, c.Path()+"\n")
    	})
    	g.GET("-2", func(c *echo.Context) error {
    		return c.String(http.StatusOK, c.Path()+"\n")
    	})
    
    	if err := e.Start(":8080"); err != nil {
    		slog.Error("Failed to start server", "error", err)
    	}
    }
    [x@x testdata]$ curl http://localhost:8080/prefix-1
    /prefix-1
    [x@x testdata]$ curl http://localhost:8080/prefix-2
    /prefix-2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions