{"record":{"id":"a1e4274583bbb119","repo":"cilium/cilium","slug":"failed-to-retrieve-objects-by-index-q-with-value","errorCode":null,"errorMessage":"failed to retrieve objects by index %q with value %q: %w","messagePattern":"failed to retrieve objects by index %q with value %q: %w","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"pkg/clustermesh/operator/cache_store.go","lineNumber":50,"sourceCode":"\titemAny, exists, _ := s.indexer.Get(obj)\n\tif exists {\n\t\titem = itemAny.(T)\n\t}\n\treturn item, exists\n}\n\nfunc (s *CacheStore[T]) GetByKey(key string) (item T, exists bool) {\n\titemAny, exists, _ := s.indexer.GetByKey(key)\n\tif exists {\n\t\titem = itemAny.(T)\n\t}\n\treturn item, exists\n}\n\nfunc (s *CacheStore[T]) MustByIndex(indexName, indexedValue string) []T {\n\titems, err := s.indexer.ByIndex(indexName, indexedValue)\n\tif err != nil {\n\t\tpanic(fmt.Errorf(\"failed to retrieve objects by index %q with value %q: %w\", indexName, indexedValue, err))\n\t}\n\treturn cslices.Map(items, func(item any) T {\n\t\treturn item.(T)\n\t})\n}\n\nfunc (s *CacheStore[T]) Update(obj T) {\n\t_ = s.indexer.Update(obj)\n}\n\nfunc (s *CacheStore[T]) Delete(obj T) {\n\t_ = s.indexer.Delete(obj)\n}\n","sourceCodeStart":32,"sourceCodeEnd":64,"githubUrl":"https://github.com/cilium/cilium/blob/ac7b90affa4baf0642e6685319d56907b3a73a6d/pkg/clustermesh/operator/cache_store.go#L32-L64","documentation":"MustByIndex queries a generic CacheStore via a client-go indexer and, by contract (Must*), panics instead of returning an error when indexer.ByIndex fails. ByIndex itself only errors when the named index does not exist on the indexer, so this panic almost always means an index name typo or a missing AddIndexers registration.","triggerScenarios":"Calling MustByIndex with an indexName that was never registered via AddIndexers on the underlying cache.Indexer, or calling it before indexers were added; the wrapped error from ByIndex is embedded in the panic value.","commonSituations":"Refactoring/renaming an index constant without updating the query site; constructing a CacheStore and forgetting AddIndexers; test code asserting on indexes that production setup code registers.","solutions":["Confirm the indexName string exactly matches an index registered with cache.AddIndexers for this store.","Add the missing AddIndexers call when initializing the CacheStore before any MustByIndex use.","Replace the panic with a checked ByIndex variant if the index name is dynamic or user-supplied.","Add a startup-time assertion/unit test that every queried index is registered."],"exampleFix":"// before\nitems := store.MustByIndex(\"byService\", svcName) // panics: index never registered\n// after\nerr := store.AddIndexers(cache.Indexers{\"byService\": serviceIndexFunc})\nif err != nil { return err }\nitems := store.MustByIndex(\"byService\", svcName)","handlingStrategy":"validation","validationCode":"// ensure index registered before use\nif _, found := indexer.GetIndexers()[\"byService\"]; !found {\n    panic(\"index byService not registered: call AddIndexers first\")\n}","typeGuard":null,"tryCatchPattern":"func() (items []T) {\n    defer func() {\n        if r := recover(); r != nil {\n            log.Errorf(\"MustByIndex failed: %v\", r)\n            items = nil\n        }\n    }()\n    return store.MustByIndex(indexName, value)\n}()","preventionTips":["Define index names as shared constants used by both AddIndexers and MustByIndex.","Add a startup assertion that every queried index exists in the indexer.","Prefer an error-returning ByIndex wrapper for any index name that is not compile-time constant."],"tags":["panic","indexer","cache","client-go"],"backgroundTag":"index-not-registered","analyzedSha":"ac7b90affa4baf0642e6685319d56907b3a73a6d","analyzedAt":"2026-08-31T18:27:15.868Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}