{"record":{"id":"ab1b2579c8491baf","repo":"derailed/k9s","slug":"expected-referenceres-but-got-t","errorCode":null,"errorMessage":"expected ReferenceRes, but got %T","messagePattern":"expected ReferenceRes, but got %T","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/render/reference.go","lineNumber":42,"sourceCode":"\t\treturn tcell.ColorCadetBlue\n\t}\n}\n\n// Header returns a header row.\nfunc (Reference) Header(string) model1.Header {\n\treturn model1.Header{\n\t\tmodel1.HeaderColumn{Name: \"NAMESPACE\"},\n\t\tmodel1.HeaderColumn{Name: \"NAME\"},\n\t\tmodel1.HeaderColumn{Name: \"GVR\"},\n\t}\n}\n\n// Render renders a K8s resource to screen.\n// BOZO!! Pass in a row with pre-alloc fields??\nfunc (Reference) Render(o any, _ string, r *model1.Row) error {\n\tref, ok := o.(ReferenceRes)\n\tif !ok {\n\t\treturn fmt.Errorf(\"expected ReferenceRes, but got %T\", o)\n\t}\n\n\tr.ID = client.FQN(ref.Namespace, ref.Name)\n\tr.Fields = append(r.Fields,\n\t\tref.Namespace,\n\t\tref.Name,\n\t\tref.GVR,\n\t)\n\n\treturn nil\n}\n\n// ----------------------------------------------------------------------------\n// Helpers...\n\n// ReferenceRes represents a reference resource.\ntype ReferenceRes struct {\n\tNamespace string","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/derailed/k9s/blob/2d3ccc6ba2ce98c3781bfc441bb3e884f072774f/internal/render/reference.go#L24-L60","documentation":"Reference.Render draws the reference browser (NAMESPACE/NAME/GVR rows) and requires a render.ReferenceRes value — the lightweight struct {Namespace, Name, GVR} built when resolving object references. The comma-ok assertion matches the value type, so a *ReferenceRes pointer or any other payload fails with this error, printing the actual %T.","triggerScenarios":"Calling Reference{}.Render with &ReferenceRes{...} (pointer), an unstructured resource, or a typed object; wiring the reference renderer to views that emit different row types.","commonSituations":"Building describe-style or cross-reference views; plugins that resolve GVK/GVR references; refactors that change the reference walker's output to pointers.","solutions":["Pass render.ReferenceRes by value","Bind the Reference renderer only to views that produce ReferenceRes rows","Use the comma-ok form in wrappers and skip mismatches","Check the %T in the error to find the offending producer"],"exampleFix":"// before\nerr := refRenderer.Render(&render.ReferenceRes{Namespace: ns, Name: n, GVR: gvr}, ns, row)\n// after\nerr := refRenderer.Render(render.ReferenceRes{Namespace: ns, Name: n, GVR: gvr}, ns, row)","handlingStrategy":"type-guard","validationCode":"// gate before invoking the reference renderer\nif _, ok := o.(render.ReferenceRes); !ok {\n\treturn fmt.Errorf(\"reference view requires render.ReferenceRes value, got %T\", o)\n}\nerr := refRenderer.Render(o, ns, row)","typeGuard":"func isReferenceRes(o any) bool {\n\t_, ok := o.(render.ReferenceRes)\n\treturn ok\n}","tryCatchPattern":"if err := refRenderer.Render(o, ns, row); err != nil {\n\tslog.Warn(\"reference row skipped\", \"type\", fmt.Sprintf(\"%T\", o), slogs.Error, err)\n\treturn nil // drop the row, keep the view alive\n}","preventionTips":["Reference.Render asserts the value type: pass ReferenceRes, not *ReferenceRes","Keep reference walkers emitting values; change both sides together if switching to pointers","Bind the Reference renderer only to reference-producing views","Use comma-ok assertions at custom call sites"],"tags":["kubernetes","go","type-assertion","references","renderer","k9s"],"backgroundTag":null,"analyzedSha":"2d3ccc6ba2ce98c3781bfc441bb3e884f072774f","analyzedAt":"2026-08-15T16:09:14.432Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}