{"id":"eee5b09cc1cf4bf7","repo":"gofiber/fiber","slug":"state-service-not-found","errorCode":null,"errorMessage":"state: service not found!","messagePattern":"state: service not found!","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"state.go","lineNumber":315,"sourceCode":"\t\t}\n\t\treturn true\n\t})\n\n\treturn length\n}\n\n// GetService returns a service present in the application's State.\nfunc GetService[T Service](s *State, key string) (T, bool) {\n\tsrv, ok := GetState[T](s, s.serviceKey(key))\n\treturn srv, ok\n}\n\n// MustGetService returns a service present in the application's State.\n// It panics if the service is not found.\nfunc MustGetService[T Service](s *State, key string) T {\n\tsrv, ok := GetService[T](s, key)\n\tif !ok {\n\t\tpanic(\"state: service not found!\")\n\t}\n\n\treturn srv\n}\n","sourceCodeStart":297,"sourceCodeEnd":320,"githubUrl":"https://github.com/gofiber/fiber/blob/9a4c7e57fe0b080a04235d28a4b0d2b4b353d58c/state.go#L297-L320","documentation":"Raised by MustGetService[T Service] (state.go:315) when GetService[T] returns ok==false. Services are stored under a hashed key: servicePrefix (a per-process random hash, servicesStatePrefix + uuid, generated in init at state.go:16) concatenated with hex(srv.String()) via serviceKey (state.go:241-244). A service is only placed into State by App.startServices (services.go:100) AFTER srv.Start() returns nil for entries in fiber.Config.Services. So the panic means one of: the service was never configured, Start() failed so it was never setService'd, the lookup key != srv.String(), or the type parameter T doesn't match the registered concrete type.","triggerScenarios":"Call fiber.MustGetService[*Cache](app.State(), \"cache\") when: Cache isn't in app.Config().Services; its Start() returned an error so setService was never called (services.go:98-101); the key passed differs from the service's String() return value; or T differs from the registered concrete type. Also triggered by querying a service on a different App/State instance than the one that ran startServices.","commonSituations":"Forgetting to add the service to Config.Services; a mismatch between the service's String() implementation and the lookup literal; a service that failed to start silently (error swallowed) or an app boot path that skipped initServices; querying from a second App instance; refactoring String() without updating call sites.","solutions":["Ensure the service is listed in fiber.Config{Services: []fiber.Service{...}} and that its Start() returns nil — startServices only setService's on success (services.go:98-101).","Make the lookup key byte-identical to srv.String(); use one shared constant at registration and retrieval.","Use fiber.GetService[T] (comma-ok) to handle absence gracefully instead of MustGetService.","Confirm you query the same App whose startServices ran — services live on that app's app.state, keyed by its per-process servicePrefix."],"exampleFix":"// before — panics if service is absent, not started, key mismatches, or wrong type\nsvc := fiber.MustGetService[*Cache](app.State(), \"cache\")\n\n// after — derive the key from the service's String() and guard the lookup\nconst cacheKey = \"cache\" // == cache.String()\n// registration: fiber.Config{Services: []fiber.Service{cache}}\nsrv, ok := fiber.GetService[*Cache](app.State(), cacheKey)\nif !ok {\n\treturn fmt.Errorf(\"service %q not available (not configured, failed to start, or wrong type)\", cacheKey)\n}","handlingStrategy":"validation","validationCode":"const key = \"cache\" // must equal cache.String()\nsrv, ok := fiber.GetService[*Cache](app.State(), key)\nif !ok {\n\treturn fmt.Errorf(\"service %q not available (not configured, Start failed, key mismatch, or wrong type)\", key)\n}","typeGuard":"func serviceAvailable[T fiber.Service](s *fiber.State, key string) bool {\n\t_, ok := fiber.GetService[T](s, key)\n\treturn ok\n}","tryCatchPattern":"defer func() {\n\tif r := recover(); r != nil {\n\t\tif msg, _ := r.(string); strings.Contains(msg, \"service not found\") {\n\t\t\tlog.Printf(\"service lookup failed: %v\", r)\n\t\t\treturn\n\t\t}\n\t\tpanic(r)\n\t}\n}()\nsvc := fiber.MustGetService[*Cache](app.State(), \"cache\")","preventionTips":["Derive lookup keys from srv.String() via a shared constant so registration and retrieval can't drift.","Always add the service to Config.Services and surface/log every Start() error so silent start failures don't hide as 'not found'.","Prefer fiber.GetService[T] over MustGetService[T] in request handlers.","Query services only on the App instance that ran startServices — the servicePrefix is per-process and per-State."],"tags":["services","state","dependency-injection","panic","lifecycle"],"analyzedSha":"9a4c7e57fe0b080a04235d28a4b0d2b4b353d58c","analyzedAt":"2026-08-04T21:44:03.395Z","schemaVersion":2}