{"id":"20873288e19964f4","repo":"gofiber/fiber","slug":"fiber-service-at-index-d-is-nil","errorCode":null,"errorMessage":"fiber: service at index %d is nil","messagePattern":"fiber: service at index (.+?) is nil","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"services.go","lineNumber":40,"sourceCode":"\tState(ctx context.Context) (string, error)\n\n\t// Terminate terminates the service, returning an error if it fails.\n\tTerminate(ctx context.Context) error\n}\n\n// hasConfiguredServices Checks if there are any services for the current application.\nfunc (app *App) hasConfiguredServices() bool {\n\treturn len(app.configured.Services) > 0\n}\n\nfunc (app *App) validateConfiguredServices() error {\n\treturn validateServicesSlice(app.configured.Services)\n}\n\nfunc validateServicesSlice(services []Service) error {\n\tfor idx, srv := range services {\n\t\tif srv == nil {\n\t\t\treturn fmt.Errorf(\"fiber: service at index %d is nil\", idx)\n\t\t}\n\t}\n\treturn nil\n}\n\n// initServices If the app is configured to use services, this function registers\n// a post shutdown hook to shutdown them after the server is closed.\n// This function panics if there is an error starting the services.\nfunc (app *App) initServices() {\n\tif !app.hasConfiguredServices() {\n\t\treturn\n\t}\n\n\tif err := app.startServices(app.servicesStartupCtx()); err != nil {\n\t\tpanic(err)\n\t}\n}\n","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/gofiber/fiber/blob/9a4c7e57fe0b080a04235d28a4b0d2b4b353d58c/services.go#L22-L58","documentation":"Returned by validateServicesSlice (services.go:40) when the config.Services slice passed to the Fiber app contains a nil entry. Fiber refuses to boot because a nil Service has no Start/Terminate methods and would panic later. The index in the message identifies exactly which slice position is nil.","triggerScenarios":"Configuring app with fiber.Config{Services: []fiber.Service{someService, nil}} and then calling app.New() (validateConfiguredServices runs during construction). Also triggered by app.startServices in initServices.","commonSituations":"Conditional service registration that appends a nil when a flag is off (e.g. svc := maybeNewService(); Services: []Service{svc}), or a factory returning nil on partial failure. Refactoring that leaves a placeholder nil in a service list.","solutions":["Filter nils out of the Services slice before passing it to fiber.New: only append non-nil services.","Fix the service factory to never return nil; return an error instead and handle it.","Use a guard helper: services = append(services, svc) only when svc != nil."],"exampleFix":"// before\nservices := []fiber.Service{redisSvc, nil, metricsSvc}\napp := fiber.New(fiber.Config{Services: services})\n\n// after: build defensively\nvar services []fiber.Service\nfor _, s := range []fiber.Service{redisSvc, maybeMetricsSvc, metricsSvc} {\n    if s != nil {\n        services = append(services, s)\n    }\n}\napp := fiber.New(fiber.Config{Services: services})","handlingStrategy":"validation","validationCode":"services := []fiber.Service{a, b, c}\nnonNil := services[:0]\nfor _, s := range services {\n    if s != nil {\n        nonNil = append(nonNil, s)\n    }\n}\napp := fiber.New(fiber.Config{Services: nonNil})","typeGuard":"func isNonNilServices(s []fiber.Service) bool {\n    for _, srv := range s {\n        if srv == nil { return false }\n    }\n    return true\n}","tryCatchPattern":null,"preventionTips":["Build the Services slice with append guarded by != nil.","Service factories should return (Service, error), never nil.","Run validateConfiguredServices() in a bootstrap test."],"tags":["services","config","startup","nil-check"],"analyzedSha":"9a4c7e57fe0b080a04235d28a4b0d2b4b353d58c","analyzedAt":"2026-08-04T21:44:03.395Z","schemaVersion":2}