{"id":"29bd1dd346e8e6c3","repo":"labstack/echo","slug":"invalid-redirect-code-for-remove-trailing-slash-mi","errorCode":null,"errorMessage":"invalid redirect code for remove trailing slash middleware","messagePattern":"invalid redirect code for remove trailing slash middleware","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"middleware/slash.go","lineNumber":109,"sourceCode":"//\n// Usage `Echo#Pre(RemoveTrailingSlash())`\nfunc RemoveTrailingSlash() echo.MiddlewareFunc {\n\treturn RemoveTrailingSlashWithConfig(RemoveTrailingSlashConfig{})\n}\n\n// RemoveTrailingSlashWithConfig returns a RemoveTrailingSlash middleware with config or panics on invalid configuration.\nfunc RemoveTrailingSlashWithConfig(config RemoveTrailingSlashConfig) echo.MiddlewareFunc {\n\treturn toMiddlewareOrPanic(config)\n}\n\n// ToMiddleware converts RemoveTrailingSlashConfig to middleware or returns an error for invalid configuration\nfunc (config RemoveTrailingSlashConfig) ToMiddleware() (echo.MiddlewareFunc, error) {\n\tif config.Skipper == nil {\n\t\tconfig.Skipper = DefaultSkipper\n\t}\n\tif config.RedirectCode != 0 && (config.RedirectCode < http.StatusMultipleChoices || config.RedirectCode > http.StatusPermanentRedirect) {\n\t\t// this is same check as `echo.context.Redirect()` does, but we can check this before even serving the request.\n\t\treturn nil, errors.New(\"invalid redirect code for remove trailing slash middleware\")\n\t}\n\n\treturn func(next echo.HandlerFunc) echo.HandlerFunc {\n\t\treturn func(c *echo.Context) error {\n\t\t\tif config.Skipper(c) {\n\t\t\t\treturn next(c)\n\t\t\t}\n\n\t\t\treq := c.Request()\n\t\t\turl := req.URL\n\t\t\tpath := url.Path\n\t\t\tqs := c.QueryString()\n\t\t\tl := len(path) - 1\n\t\t\tif l > 0 && strings.HasSuffix(path, \"/\") {\n\t\t\t\tpath = path[:l]\n\t\t\t\turi := path\n\t\t\t\tif qs != \"\" {\n\t\t\t\t\turi += \"?\" + qs","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/labstack/echo/blob/05489dc1730161df26b72d1ae2a3ba6fb8178fc7/middleware/slash.go#L91-L127","documentation":"Returned by RemoveTrailingSlashConfig.ToMiddleware when RedirectCode is non-zero and outside [300, 308]. Identical guard to AddTrailingSlash: 0 means internal rewrite, any other value must be a 3xx redirect status.","triggerScenarios":"Calling RemoveTrailingSlashWithConfig(RemoveTrailingSlashConfig{RedirectCode: 301}) is fine; passing 200, 309, 404, etc. triggers the error.","commonSituations":"Developer passes http.StatusOK or a non-redirect constant; or confuses RedirectCode=0 (internal forward) with 'use default redirect'.","solutions":["Use a 3xx code such as http.StatusMovedPermanently (301).","Leave RedirectCode at 0 if you want the path rewritten internally without an HTTP redirect.","Validate the constant is within 300-308 before wiring.","Use config.ToMiddleware() to receive the error rather than a panic."],"exampleFix":"// before\nm := middleware.RemoveTrailingSlashWithConfig(middleware.RemoveTrailingSlashConfig{RedirectCode: http.StatusFound})\n// after (or omit RedirectCode for internal forward)\nm := middleware.RemoveTrailingSlashWithConfig(middleware.RemoveTrailingSlashConfig{RedirectCode: http.StatusMovedPermanently})","handlingStrategy":"validation","validationCode":"func isValidRedirectCode(code int) bool {\n    return code == 0 || (code >= 300 && code <= 308)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use a 3xx constant for RedirectCode, or leave it 0 for internal rewrite (no HTTP redirect).","Do not pass 2xx/4xx/5xx codes; they are not redirects.","If the code is configurable, validate the range before constructing the middleware."],"tags":["middleware","trailing-slash","redirect","config","panic","startup"],"analyzedSha":"05489dc1730161df26b72d1ae2a3ba6fb8178fc7","analyzedAt":"2026-08-04T21:32:47.783Z","schemaVersion":2}