{"record":{"id":"b4012ae431356fd9","repo":"cilium/cilium","slug":"failed-to-decode-non-unstructured-object","errorCode":null,"errorMessage":"failed to decode non-Unstructured object","messagePattern":"failed to decode non-Unstructured object","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cilium-cli/k8s/tables.go","lineNumber":20,"sourceCode":"// Copyright Authors of Cilium\n\npackage k8s\n\nimport (\n\t\"fmt\"\n\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured\"\n\t\"k8s.io/apimachinery/pkg/runtime\"\n)\n\nfunc unstructuredToTable(o runtime.Object) (*metav1.Table, error) {\n\tif metav1.SchemeGroupVersion.WithKind(\"Table\") != o.GetObjectKind().GroupVersionKind() {\n\t\treturn nil, fmt.Errorf(\"failed to decode non-Table object\")\n\t}\n\tu, ok := o.(*unstructured.Unstructured)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"failed to decode non-Unstructured object\")\n\t}\n\tt := &metav1.Table{}\n\tif err := runtime.DefaultUnstructuredConverter.FromUnstructured(u.Object, t); err != nil {\n\t\treturn nil, err\n\t}\n\tfor i := range t.Rows {\n\t\trow := &t.Rows[i]\n\t\tif row.Object.Raw == nil || row.Object.Object != nil {\n\t\t\tcontinue\n\t\t}\n\t\tconverted, err := runtime.Decode(unstructured.UnstructuredJSONScheme, row.Object.Raw)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\trow.Object.Object = converted\n\t}\n\treturn t, nil\n}","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/cilium/cilium/blob/ac7b90affa4baf0642e6685319d56907b3a73a6d/cilium-cli/k8s/tables.go#L2-L38","documentation":"After confirming the object claims Table kind, unstructuredToTable requires the concrete Go type to be *unstructured.Unstructured so its raw map can be converted into metav1.Table. If the object is some other runtime.Object implementation, this error is returned. It signals a decoding/typing mismatch in the caller's pipeline.","triggerScenarios":"Calling unstructuredToTable/unstructuredSliceToTable with an object that passed the Table GVK check but is a typed struct (e.g. *corev1.PodList) or a custom runtime.Object rather than *unstructured.Unstructured.","commonSituations":"Mixing typed clientset results into the unstructured table pipeline; custom decoders producing typed objects; refactoring that changed the decode path.","solutions":["Decode the response into unstructured.Unstructured (e.g. via runtime.DecodeInto with an unstructured decoder)","Ensure the list request goes through the RESTClient returning unstructured data, not the typed clientset","Convert the typed object to unstructured via runtime.DefaultUnstructuredConverter.ToUnstructured before passing"],"exampleFix":"// before\npods, _ := clientset.CoreV1().Pods(ns).List(ctx, metav1.ListOptions{})\ntable, err := unstructuredSliceToTable([]runtime.Object{pods})\n// after\nu := &unstructured.Unstructured{}\nuntime.DefaultUnstructuredConverter.ToUnstructured(pods, &u.Object)\ntable, err := unstructuredSliceToTable([]runtime.Object{u})","handlingStrategy":"type-guard","validationCode":"if _, ok := obj.(*unstructured.Unstructured); !ok {\n\treturn errors.New(\"object must be *unstructured.Unstructured for table conversion\")\n}","typeGuard":"func isUnstructured(o runtime.Object) (*unstructured.Unstructured, bool) {\n\tu, ok := o.(*unstructured.Unstructured)\n\treturn u, ok\n}","tryCatchPattern":"table, err := unstructuredToTable(o)\nif err != nil && strings.Contains(err.Error(), \"non-Unstructured\") {\n\tu := &unstructured.Unstructured{}\n\truntime.DefaultUnstructuredConverter.ToUnstructured(o, &u.Object)\n\ttable, err = unstructuredToTable(u)\n}","preventionTips":["Keep table rendering on the unstructured/RESTClient path, not the typed clientset","Convert typed objects with DefaultUnstructuredConverter before table conversion","Centralize decoding in one place to avoid mixed types"],"tags":["kubernetes","table","unstructured","type-mismatch"],"backgroundTag":"object-type-mismatch","analyzedSha":"ac7b90affa4baf0642e6685319d56907b3a73a6d","analyzedAt":"2026-08-31T18:27:15.868Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}