{"record":{"id":"52be76e7777b5533","repo":"derailed/k9s","slug":"expecting-service-resource-52be76","errorCode":null,"errorMessage":"expecting Service resource","messagePattern":"expecting Service resource","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/dao/svc.go","lineNumber":62,"sourceCode":"\tsvc, err := s.GetInstance(fqn)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn podFromSelector(s.Factory, svc.Namespace, svc.Spec.Selector)\n}\n\n// GetInstance returns a service instance.\nfunc (s *Service) GetInstance(fqn string) (*v1.Service, error) {\n\to, err := s.getFactory().Get(s.gvr, fqn, true, labels.Everything())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar svc v1.Service\n\terr = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &svc)\n\tif err != nil {\n\t\treturn nil, errors.New(\"expecting Service resource\")\n\t}\n\n\treturn &svc, nil\n}\n\n// ----------------------------------------------------------------------------\n// Helpers...\n\nfunc podFromSelector(f Factory, ns string, sel map[string]string) (string, error) {\n\too, err := f.List(client.PodGVR, ns, true, labels.Set(sel).AsSelector())\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tif len(oo) == 0 {\n\t\treturn \"\", fmt.Errorf(\"no matching pods for %v\", sel)\n\t}\n","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/derailed/k9s/blob/2d3ccc6ba2ce98c3781bfc441bb3e884f072774f/internal/dao/svc.go#L44-L80","documentation":"Service.GetInstance fetches the service by FQN and converts the unstructured object to the typed v1.Service. If conversion fails (payload shape does not match core/v1 Service), the typed error is discarded and this sentinel returned. Callers use it to resolve headless services in front of StatefulSets and to build port-forwards.","triggerScenarios":"GetInstance on an FQN whose stored object is not a core/v1 Service — wrong GVR passed to Init, an object mutated by a webhook with fields the converter rejects, or schema mismatch between compiled client-go and the cluster.","commonSituations":"Clusters with service- mutating admission plugins; version skew between k9s and API server; custom code constructing the Service DAO against an Endpoint or ExternalName variant carrying unexpected fields.","solutions":["Verify the object: kubectl get svc <fqn> -o yaml must round-trip as core/v1 Service.","Ensure the DAO was Init'ed with client.SvcGVR and the factory cache is fresh (restart k9s after upgrades).","Wrap the conversion error (%w) to expose the failing field instead of the generic message."],"exampleFix":"// before\nif err != nil { return nil, errors.New(\"expecting Service resource\") }\n// after\nif err != nil { return nil, fmt.Errorf(\"expecting Service resource: %w\", err) }","handlingStrategy":"type-guard","validationCode":"u, ok := o.(*unstructured.Unstructured)\nif !ok || u.GetKind() != \"Service\" {\n    return nil, fmt.Errorf(\"expected core/v1 Service, got %s/%s\", u.GetAPIVersion(), u.GetKind())\n}","typeGuard":"func isService(o runtime.Object) bool {\n    u, ok := o.(*unstructured.Unstructured)\n    return ok && u.GetKind() == \"Service\" && u.GetAPIVersion() == \"v1\"\n}","tryCatchPattern":"svc, err := svcDAO.GetInstance(fqn)\nif err != nil {\n    if strings.Contains(err.Error(), \"expecting Service resource\") { /* schema/object mismatch */ }\n    return err\n}","preventionTips":["Init the Service DAO with client.SvcGVR only.","Verify with kubectl that the object round-trips as core/v1 Service.","Wrap conversion errors with %w when extending this code."],"tags":["go","kubernetes","service","conversion","dao"],"backgroundTag":null,"analyzedSha":"2d3ccc6ba2ce98c3781bfc441bb3e884f072774f","analyzedAt":"2026-08-15T16:09:14.432Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}