gofiber/fiber · critical
route handler 'fn' cannot be nil
Error message
route handler 'fn' cannot be nil
What it means
App.Route(prefix, fn) requires a non-nil function that registers routes on the sub-router; calling it with a nil fn panics immediately. The guard prevents a silent no-op route group, which would be a confusing runtime defect.
Solutions
- Ensure the function passed to Route is a non-nil func(router fiber.Router).
- If routes are optional, guard the call: if register != nil { app.Route("/api", register) }.
- Load modules eagerly and fail loudly if a route registrar is missing rather than passing nil.
Example fix
// before
app.Route("/api", moduleLoader.Get("api")) // returns nil when missing
// after
reg := moduleLoader.Get("api")
if reg == nil { log.Fatal("api route registrar missing") }
app.Route("/api", reg) Defensive patterns
Strategy: validation
Validate before calling
// Guard Route against nil registrars
func routeIf(app *fiber.App, prefix string, fn func(fiber.Router)) {
if fn == nil { return }
app.Route(prefix, fn)
} Type guard
func isRouteFn(v any) bool {
f, ok := v.(func(fiber.Router))
return ok && f != nil
} Prevention
- Load route registrars eagerly and fail loudly if missing.
- Use a helper that no-ops on nil rather than passing nil to Route.
- Type-check plugin return values at load time.
When it happens
Trigger: Passing a nil function as the second argument: app.Route("/api", nil). Common when the route-registration function is conditionally assigned or fetched from a map and ends up nil.
Common situations: Plugin/module loader returning nil for a missing module; conditional route setup where the closure variable was never assigned; refactor leaving a dangling nil.
Related errors
- route handler 'fn' cannot be nil
- route handler 'fn' cannot be nil
- Domain pattern cannot be empty
- Domain pattern ' ' contains empty label at position
- Domain pattern ' ' contains empty parameter name at position
AI-assisted analysis of gofiber/fiber@a105acad6c (2026-08-11).
Data as JSON: /api/errors/f7ba542335cb6250.
Report an issue: GitHub.
Appendix: source
Thrown at app.go:1201
}
}
// RouteChain creates a Registering instance that lets you declare a stack of
// handlers for the same route. Handlers defined via the returned Register are
// scoped to the provided path.
func (app *App) RouteChain(path string) Register {
// Create new route
route := &Registering{app: app, path: path}
return route
}
// Route is used to define routes with a common prefix inside the supplied
// function. It mirrors the legacy helper and reuses the Group method to create
// a sub-router.
func (app *App) Route(prefix string, fn func(router Router), name ...string) Router {
if fn == nil {
panic("route handler 'fn' cannot be nil")
}
// Create new group
group := app.Group(prefix)
if len(name) > 0 {
group.Name(name[0])
}
// Define routes
fn(group)
return group
}
// Error makes it compatible with the `error` interface.
func (e *Error) Error() string {
return e.Message
}
View on GitHub (pinned to a105acad6c)