{"record":{"id":"ec148d5c4416ccc8","repo":"derailed/k9s","slug":"strings-join-errs","errorCode":null,"errorMessage":"strings.Join(errs, \" - \")","messagePattern":"strings\\.Join\\(errs, \" - \"\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"internal/render/crd.go","lineNumber":132,"sourceCode":"\t\t\t\tee = append(ee, fmt.Errorf(\"%s\", *v.DeprecationWarning))\n\t\t\t} else {\n\t\t\t\tee = append(ee, fmt.Errorf(\"%s[%s] is deprecated\", n, v.Name))\n\t\t\t}\n\t\t}\n\t}\n\tif !served {\n\t\tee = append(ee, fmt.Errorf(\"CRD %s is no longer served by the api server\", n))\n\t}\n\n\tif len(ee) == 0 {\n\t\treturn nil\n\t}\n\terrs := make([]string, 0, len(ee))\n\tfor _, e := range ee {\n\t\terrs = append(errs, e.Error())\n\t}\n\n\treturn errors.New(strings.Join(errs, \" - \"))\n}\n","sourceCodeStart":114,"sourceCodeEnd":134,"githubUrl":"https://github.com/derailed/k9s/blob/2d3ccc6ba2ce98c3781bfc441bb3e884f072774f/internal/render/crd.go#L114-L134","documentation":"CustomResourceDefinition.diagnose accumulates per-version findings — deprecation warnings (or the generic '<name>[<ver>] is deprecated' when a deprecated version omits a warning) and 'CRD <n> is no longer served by the api server' when no version has Served=true — then joins them with ' - ' into one error. It is the CRD list's health column: each condition is advisory, describing deprecation/serving state rather than a k9s failure.","triggerScenarios":"Viewing CRDs where at least one spec.versions[] entry has Deprecated:true (with or without deprecationWarning), or where the versions list has no entry with Served:true; multiple findings concatenate into a single dash-joined message.","commonSituations":"Operators deprecating v1beta1-style storage versions during upgrades; admins flipping Served:false during version migrations; CRDs installed with all versions unserved by mistake.","solutions":["For deprecation messages: migrate manifests/clients off the deprecated version (the message names CRD and version, or carries the upstream deprecationWarning text).","For 'no longer served': set Served:true on the intended version in the CRD spec (kubectl edit crd <name>) or remove the dead CRD.","Treat the row as a warning signal — no k9s-side remediation is expected."],"exampleFix":"# before\nversions:\n  - name: v1beta1\n    served: false\n    storage: true\n# after\nversions:\n  - name: v1\n    served: true\n    storage: true\n  - name: v1beta1\n    served: false\n    storage: false\n    deprecated: true\n    deprecationWarning: \"use v1\"","handlingStrategy":"validation","validationCode":"func crdHealthy(name string, vv []v1.CustomResourceDefinitionVersion) bool {\n    served := false\n    for _, v := range vv {\n        if v.Served { served = true }\n        if v.Deprecated { return false } // deprecation surfaces in diagnose\n    }\n    return served && len(vv) > 0\n}","typeGuard":null,"tryCatchPattern":"if err := crdDiagnose(name, versions); err != nil {\n    msg := err.Error() // dash-joined: parse segments to act per finding (deprecation vs not served)\n    if strings.Contains(msg, \"no longer served\") { /* set Served:true or delete CRD */ }\n}","preventionTips":["Set deprecationWarning on deprecated CRD versions so the message is actionable.","During version migrations keep exactly one Served+Storage version and mark old ones deprecated.","Migrate clients off deprecated versions when the warning appears."],"tags":["go","kubernetes","crd","deprecation","health-status"],"backgroundTag":null,"analyzedSha":"2d3ccc6ba2ce98c3781bfc441bb3e884f072774f","analyzedAt":"2026-08-15T16:09:14.432Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}