{"record":{"id":"7ef98103d42d397a","repo":"derailed/k9s","slug":"failed-to-decode-table-rows-w","errorCode":null,"errorMessage":"failed to decode table rows: %w","messagePattern":"failed to decode table rows: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/dao/table.go","lineNumber":137,"sourceCode":"\t\t\t}\n\t\t\trow.Object.Object = converted\n\t\t\tvar m metav1.Object\n\t\t\tif obj := row.Object.Object; obj != nil {\n\t\t\t\tm, _ = meta.Accessor(obj)\n\t\t\t}\n\t\t\tvar ns string\n\t\t\tif m != nil {\n\t\t\t\tns = m.GetNamespace()\n\t\t\t}\n\t\t\tif namespaced {\n\t\t\t\trow.Cells = append([]any{ns}, row.Cells...)\n\t\t\t}\n\t\t\treturn nil\n\t\t})\n\t}\n\terrs := pool.Drain()\n\tif len(errs) > 0 {\n\t\treturn nil, fmt.Errorf(\"failed to decode table rows: %w\", errs[0])\n\t}\n\n\treturn table, nil\n}\n\nfunc (t *Table) getClient(f serializer.CodecFactory) (*rest.RESTClient, error) {\n\tcfg, err := t.Client().RestConfig()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tgv := t.gvr.GV()\n\tcfg.GroupVersion = &gv\n\tcfg.APIPath = \"/apis\"\n\tif t.gvr.G() == \"\" {\n\t\tcfg.APIPath = \"/api\"\n\t}\n\tcfg.NegotiatedSerializer = f.WithoutConversion()\n\tcrRestClient, err := rest.RESTClientFor(cfg)","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/derailed/k9s/blob/2d3ccc6ba2ce98c3781bfc441bb3e884f072774f/internal/dao/table.go#L119-L155","documentation":"Table.List hydrates a metav1.Table by decoding each row in a worker pool (pool.Drain collects per-row errors) and reports only the first failure, wrapped as 'failed to decode table rows: %w'. The underlying cause is whatever the row decoder returned, typically a type-conversion failure on row cells or contained objects.","triggerScenarios":"Listing a resource in table format where one or more rows fail conversion: custom resources (CRDs) whose status/spec fields don't round-trip through unstructured conversion, aggregated APIServer resources with non-standard cell types, or rows referencing objects the user can partially get but whose embedded objects decode with errors.","commonSituations":"Third-party operators with loosely typed CRD schemas (float in int fields, nested maps); mixed-privilege namespaces where partial RBAC yields odd table rows; version skew between an extension API server and its CRD schema.","solutions":["Read the wrapped error (%w) first — it names the exact field/type that failed to decode","Reproduce with kubectl get <resource> -o wide / -v=6 to see whether the table conversion fails server-side too","For CRDs, validate instance payloads against the OpenAPI schema and fix offending fields (kubectl get <crd> -o yaml | kubectl validate-style checks)","Report or update the operator/extension API server if its schema serializes values the table decoder cannot convert"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"rows, err := table.List(ctx)\nif err != nil {\n    if strings.HasPrefix(err.Error(), \"failed to decode table rows\") {\n        // the wrapped cause names the offending field; log it fully and degrade to raw list\n        slog.Error(\"table decode failed\", slogs.Error, errors.Unwrap(err))\n        return listRawWithoutTableConversion(ctx) // e.g. Accept: application/json\n    }\n    return err\n}","preventionTips":["Always log the wrapped error (%w) — the outer message alone says nothing actionable","Keep CRD schemas strict (typed fields) so table row conversion cannot fail","Smoke-test list views for every CRD after operator upgrades"],"tags":["kubernetes","table","decode","crd","k9s"],"backgroundTag":null,"analyzedSha":"2d3ccc6ba2ce98c3781bfc441bb3e884f072774f","analyzedAt":"2026-08-15T16:09:14.432Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}