{"record":{"id":"6f27325ba7a8a5d8","repo":"kataras/iris","slug":"build-router-w","errorCode":null,"errorMessage":"build: router: %w","messagePattern":"build: router: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"iris.go","lineNumber":767,"sourceCode":"\t\tif _, err := injectLiveReload(app); err != nil {\n\t\t\treturn fmt.Errorf(\"build: inject live reload: failed: %v\", err)\n\t\t}\n\n\t\tif app.config.ForceLowercaseRouting {\n\t\t\t// This should always be executed first.\n\t\t\tapp.Router.PrependRouterWrapper(func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {\n\t\t\t\tr.Host = strings.ToLower(r.Host)\n\t\t\t\tr.URL.Host = strings.ToLower(r.URL.Host)\n\t\t\t\tr.URL.Path = strings.ToLower(r.URL.Path)\n\t\t\t\tnext(w, r)\n\t\t\t})\n\t\t}\n\n\t\t// create the request handler, the default routing handler\n\t\trouterHandler := router.NewDefaultHandler(app.config, app.logger)\n\t\terr := app.Router.BuildRouter(app.ContextPool, routerHandler, app.APIBuilder, false)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"build: router: %w\", err)\n\t\t}\n\t\tapp.HTTPErrorHandler = routerHandler\n\n\t\tif app.config.Timeout > 0 {\n\t\t\tapp.Router.SetTimeoutHandler(app.config.Timeout, app.config.TimeoutMessage)\n\n\t\t\tapp.ConfigureHost(func(su *Supervisor) {\n\t\t\t\tif su.Server.ReadHeaderTimeout == 0 {\n\t\t\t\t\tsu.Server.ReadHeaderTimeout = app.config.Timeout + 5*time.Second\n\t\t\t\t}\n\n\t\t\t\tif su.Server.ReadTimeout == 0 {\n\t\t\t\t\tsu.Server.ReadTimeout = app.config.Timeout + 10*time.Second\n\t\t\t\t}\n\n\t\t\t\tif su.Server.WriteTimeout == 0 {\n\t\t\t\t\tsu.Server.WriteTimeout = app.config.Timeout + 15*time.Second\n\t\t\t\t}","sourceCodeStart":749,"sourceCodeEnd":785,"githubUrl":"https://github.com/kataras/iris/blob/7bedaf55a0b64bbb2248a5845a2c60d81a30996a/iris.go#L749-L785","documentation":"Iris wraps errors from Router.BuildRouter during app build as 'build: router: %w'. BuildRouter compiles the APIBuilder's registered routes into the radix/trie router; failures almost always come from invalid route registrations — duplicate paths, invalid parameter types, or conflicting wildcards.","triggerScenarios":"Registering two identical routes on the same method/path; using %v invalid macro expressions like /{param:int:min=1:min=2}; wildcard params ({param:path}) not at the end of the path; conflicting static vs wildcard segments on the same subtree; calling Build via New/Run after such registrations.","commonSituations":"Auto-generating routes in a loop that registers the same handler path twice; refactoring a path from /users/{id} to /users/{id:path} while keeping /users/all; upgrading Iris where stricter trie validation rejects paths previously tolerated (see #2024-style checks).","solutions":["Read the wrapped error after 'build: router:' — it names the exact conflicting route.","Search your route registrations for duplicates: same HTTP method + path registered more than once.","Ensure wildcard/path parameters appear only as the final segment (e.g. /files/{p:path}, not /files/{p:path}/more).","Ensure each path segment contains at most one dynamic parameter (no /files/{name}-{ext}).","Log every registered route before Run() and diff for unintended duplicates."],"exampleFix":"// before (duplicate + mid-path wildcard)\napp.Get(\"/users/{id}\", getUser)\napp.Get(\"/users/{id}\", getUserV2)\napp.Get(\"/files/{p:path}/raw\", raw)\n// after\napp.Get(\"/users/{id}\", getUser) // single registration\napp.Get(\"/files/{p:path}\", raw)","handlingStrategy":"validation","validationCode":"seen := map[string]string{}\nfor _, r := range routes {\n    key := r.Method + \" \" + normalize(r.Path)\n    if prev, dup := seen[key]; dup {\n        log.Fatalf(\"duplicate route %s (also %s)\", key, prev)\n    }\n    seen[key] = key\n    if strings.Count(seg, \"{\") > 1 || hasWildcardMidPath(r.Path) {\n        log.Fatalf(\"invalid route path %s\", r.Path)\n    }\n}","typeGuard":"func hasWildcardMidPath(p string) bool {\n    parts := strings.Split(strings.Trim(p, \"/\"), \"/\")\n    for i, s := range parts {\n        if strings.HasSuffix(s, \":path}\") && i < len(parts)-1 {\n            return true\n        }\n    }\n    return false\n}","tryCatchPattern":"if err := app.Run(iris.Addr(\":8080\")); err != nil {\n    if strings.Contains(err.Error(), \"build: router:\") {\n        log.Fatalf(\"route registration problem: %v\", err)\n    }\n    log.Fatal(err)\n}","preventionTips":["Keep a single source of truth for route registration to avoid duplicates.","Never place {param:path} anywhere but the last segment.","Never mix dynamic params with static text in one segment.","Write a startup test that builds the app in CI."],"tags":["go","iris","router","routes","startup"],"backgroundTag":"route-registration-conflict","analyzedSha":"7bedaf55a0b64bbb2248a5845a2c60d81a30996a","analyzedAt":"2026-08-30T20:38:16.250Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}