{"record":{"id":"4b5d968bfb72ab7d","repo":"derailed/k9s","slug":"not-a-metav1-table","errorCode":null,"errorMessage":"not a metav1.Table","messagePattern":"not a metav1\\.Table","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/dao/workload.go","lineNumber":89,"sourceCode":"\tif client.IsClusterScoped(ns) {\n\t\treturn dial.Delete(ctx, n, opts)\n\t}\n\n\treturn dial.Namespace(ns).Delete(ctx, n, opts)\n}\n\nfunc (a *Workload) fetch(ctx context.Context, gvr *client.GVR, ns string) (*metav1.Table, error) {\n\ta.gvr = gvr\n\too, err := a.Table.List(ctx, ns)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif len(oo) == 0 {\n\t\treturn nil, fmt.Errorf(\"no table found for gvr: %s\", gvr)\n\t}\n\ttt, ok := oo[0].(*metav1.Table)\n\tif !ok {\n\t\treturn nil, errors.New(\"not a metav1.Table\")\n\t}\n\n\treturn tt, nil\n}\n\n// List fetch workloads.\nfunc (a *Workload) List(ctx context.Context, ns string) ([]runtime.Object, error) {\n\too := make([]runtime.Object, 0, 100)\n\tfor _, gvr := range resList {\n\t\ttable, err := a.fetch(ctx, gvr, ns)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tvar (\n\t\t\tns string\n\t\t\tts metav1.Time\n\t\t)\n\t\tfor _, r := range table.Rows {","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/derailed/k9s/blob/2d3ccc6ba2ce98c3781bfc441bb3e884f072774f/internal/dao/workload.go#L71-L107","documentation":"Workload.fetch powers the aggregated workloads view: it asks Table.List (server-side Table conversion, Accept: as=Table) for each workload GVR and asserts the first returned object is *metav1.Table. If the API server (or something in between) returns a plain object instead of a Table, the type assertion fails. It also fails when the table row is a custom type injected by a custom view decorator.","triggerScenarios":"An API server or aggregated API that ignores the Table accept header and returns the resource list unconverted; a proxy/stripping proxy rewriting responses; cached/stale results from a custom dao.Table implementation returning non-metav1.Table runtime.Objects.","commonSituations":"Very old or non-standard Kubernetes distributions; API server behind mutating middlewares; bugs in custom resource views that replace the Table DAO's output; k9s version expecting Table semantics the server does not support.","solutions":["Verify the server supports server-side tables: kubectl get <resource> -o json with Accept as=Table, or `kubectl get --raw` with the Table accept header.","Bypass middlewares/proxies that rewrite API responses and retry the workloads view.","If implementing a custom Table DAO, make sure List returns []*metav1.Table as the stock implementation does."],"exampleFix":"// before\ntt, ok := oo[0].(*metav1.Table)\nif !ok { return nil, errors.New(\"not a metav1.Table\") }\n// after\ntt, ok := oo[0].(*metav1.Table)\nif !ok { return nil, fmt.Errorf(\"gvr %s: expected *metav1.Table, got %T\", gvr, oo[0]) }","handlingStrategy":"type-guard","validationCode":"if len(oo) == 0 { return nil, fmt.Errorf(\"no table found for gvr: %s\", gvr) } // already guarded upstream\n// verify server table support once per session\ntt, ok := oo[0].(*metav1.Table)\nif !ok { return nil, fmt.Errorf(\"gvr %s: got %T, want *metav1.Table\", gvr, oo[0]) }","typeGuard":"func isMetaTable(o runtime.Object) bool {\n    _, ok := o.(*metav1.Table)\n    return ok\n}","tryCatchPattern":"tbl, err := wl.fetch(ctx, gvr, ns)\nif err != nil {\n    if strings.Contains(err.Error(), \"not a metav1.Table\") { /* server/proxy not honoring Table accept header */ }\n    return err\n}","preventionTips":["Confirm the API server supports server-side Table conversion before using the workloads view.","Remove response-rewriting proxies between k9s and the API server.","Custom Table DAOs must return *metav1.Table objects."],"tags":["go","kubernetes","metav1-table","workloads","api-server"],"backgroundTag":null,"analyzedSha":"2d3ccc6ba2ce98c3781bfc441bb3e884f072774f","analyzedAt":"2026-08-15T16:09:14.432Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}