{"record":{"id":"74b404ced74ffcbe","repo":"derailed/k9s","slug":"expecting-daemonset-resource","errorCode":null,"errorMessage":"expecting DaemonSet resource","messagePattern":"expecting DaemonSet resource","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/dao/ds.go","lineNumber":133,"sourceCode":"\tds, err := d.GetInstance(fqn)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn podFromSelector(d.Factory, ds.Namespace, ds.Spec.Selector.MatchLabels)\n}\n\n// GetInstance returns a daemonset instance.\nfunc (d *DaemonSet) GetInstance(fqn string) (*appsv1.DaemonSet, error) {\n\to, err := d.getFactory().Get(d.gvr, fqn, true, labels.Everything())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar ds appsv1.DaemonSet\n\terr = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &ds)\n\tif err != nil {\n\t\treturn nil, errors.New(\"expecting DaemonSet resource\")\n\t}\n\n\treturn &ds, nil\n}\n\n// ScanSA scans for serviceaccount refs.\nfunc (d *DaemonSet) ScanSA(_ context.Context, fqn string, wait bool) (Refs, error) {\n\tns, n := client.Namespaced(fqn)\n\too, err := d.getFactory().List(d.gvr, ns, wait, labels.Everything())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\trefs := make(Refs, 0, len(oo))\n\tfor _, o := range oo {\n\t\tvar ds appsv1.DaemonSet\n\t\terr = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &ds)\n\t\tif err != nil {","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/derailed/k9s/blob/2d3ccc6ba2ce98c3781bfc441bb3e884f072774f/internal/dao/ds.go#L115-L151","documentation":"k9s's DaemonSet DAO fetches a single DaemonSet from the shared informer cache as *unstructured.Unstructured and converts it into appsv1.DaemonSet via runtime.DefaultUnstructuredConverter.FromUnstructured (internal/dao/ds.go:133). The sentinel 'expecting DaemonSet resource' is returned when conversion fails, and the underlying converter error is discarded. It means the cached object under daemonsets.apps does not fit the k8s.io/api schema k9s was compiled against.","triggerScenarios":"Calling dao.DaemonSet.GetInstance(fqn) — the daemonset detail view, restart or rollout actions — when the stored object has fields whose JSON types cannot be assigned to the compiled appsv1.DaemonSet struct: apiserver version skew, an aggregated API shadowing daemonsets.apps, or webhook-written out-of-schema values.","commonSituations":"k9s builds with older k8s.io/* libraries against newer clusters; DaemonSets mutated by custom controllers or webhooks with legacy fields; cache staleness right after cluster upgrades; embedding the DAO layer with a custom factory.","solutions":["Inspect the object: kubectl get daemonset.apps <name> -n <ns> -o yaml and fix mistyped or unexpected fields.","Upgrade k9s so its vendored k8s.io/* versions match the cluster minor version.","Verify daemonsets.apps is served by the core apiserver and not shadowed by an aggregated service.","Restart k9s to rebuild informer caches after cluster/webhook changes.","If embedding, wrap the converter error with %w to expose the offending field."],"exampleFix":"// before\nerr = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &ds)\nif err != nil {\n    return nil, errors.New(\"expecting DaemonSet resource\")\n}\n// after\nu, ok := o.(*unstructured.Unstructured)\nif !ok {\n    return nil, fmt.Errorf(\"expected unstructured daemonset, got %T\", o)\n}\nvar ds appsv1.DaemonSet\nif err := runtime.DefaultUnstructuredConverter.FromUnstructured(u.Object, &ds); err != nil {\n    return nil, fmt.Errorf(\"daemonset %q does not match v1 schema: %w\", fqn, err)\n}","handlingStrategy":"try-catch","validationCode":"o, err := factory.Get(client.DsGVR, fqn, true, labels.Everything())\nif err != nil { return err }\nu, ok := o.(*unstructured.Unstructured)\nif !ok || u.GroupVersionKind().Kind != \"DaemonSet\" {\n    return fmt.Errorf(\"not a daemonset: %s\", u.GroupVersionKind())\n}","typeGuard":"func isDaemonSet(o runtime.Object) bool {\n    u, ok := o.(*unstructured.Unstructured)\n    return ok && u.GroupVersionKind().Kind == \"DaemonSet\" && u.GroupVersionKind().Group == \"apps\"\n}","tryCatchPattern":"var ds appsv1.DaemonSet\nif err := runtime.DefaultUnstructuredConverter.FromUnstructured(u.Object, &ds); err != nil {\n    return nil, fmt.Errorf(\"daemonset %q conversion: %w\", fqn, err)\n}","preventionTips":["Align k9s builds with cluster versions; daemonset schemas drift across releases.","Assert *unstructured.Unstructured and the GVK before converting in custom code.","Wrap converter errors with %w instead of replacing them with sentinels.","Restart k9s after cluster or webhook changes to rebuild caches."],"tags":["kubernetes","go","type-conversion","daemonset","dao"],"backgroundTag":null,"analyzedSha":"2d3ccc6ba2ce98c3781bfc441bb3e884f072774f","analyzedAt":"2026-08-15T16:09:14.432Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}