{"record":{"id":"351fea5655d3a3df","repo":"derailed/k9s","slug":"revision-conversion-failed","errorCode":null,"errorMessage":"revision conversion failed","messagePattern":"revision conversion failed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/dao/rs.go","lineNumber":66,"sourceCode":"\t}\n\n\tvar rs appsv1.ReplicaSet\n\terr = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &rs)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &rs, nil\n}\n\nfunc getRSRevision(rs *appsv1.ReplicaSet) (int64, error) {\n\trevision := rs.Annotations[\"deployment.kubernetes.io/revision\"]\n\tif rs.Status.Replicas != 0 {\n\t\treturn 0, errors.New(\"can not rollback current replica\")\n\t}\n\tvers, err := strconv.Atoi(revision)\n\tif err != nil {\n\t\treturn 0, errors.New(\"revision conversion failed\")\n\t}\n\n\treturn int64(vers), nil\n}\n\nfunc controllerInfo(rs *appsv1.ReplicaSet) (name, kind, group string, err error) {\n\tfor _, ref := range rs.OwnerReferences {\n\t\tif ref.Controller == nil {\n\t\t\tcontinue\n\t\t}\n\t\tgroup, tokens := ref.APIVersion, strings.Split(ref.APIVersion, \"/\")\n\t\tif len(tokens) == 2 {\n\t\t\tgroup = tokens[0]\n\t\t}\n\t\treturn ref.Name, ref.Kind, group, nil\n\t}\n\n\treturn \"\", \"\", \"\", fmt.Errorf(\"unable to find controller for replicaset: %s\", rs.Name)","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/derailed/k9s/blob/2d3ccc6ba2ce98c3781bfc441bb3e884f072774f/internal/dao/rs.go#L48-L84","documentation":"getRSRevision reads the annotation \"deployment.kubernetes.io/revision\" off a ReplicaSet and converts it with strconv.Atoi to build the rollback target revision. If the annotation is absent (Atoi receives \"\"), empty, or non-numeric, conversion fails. Only ReplicaSets managed by the Deployment controller carry this annotation, so unmanaged or externally-created RSes hit this path.","triggerScenarios":"Invoking :rollback on a ReplicaSet that has no deployment.kubernetes.io/revision annotation (standalone RS, created by another controller, hand-applied YAML); the annotation value was edited to a non-numeric string.","commonSituations":"ReplicaSets created by tools that do not set the revision annotation; CRD-based or custom controllers that spawn RSes; manifest templates that strip annotations; version drift after cluster migrations that lose annotations.","solutions":["Verify the annotation exists and is numeric: kubectl get rs <name> -o jsonpath='{.metadata.annotations.deployment\\.kubernetes\\.io/revision}'.","Only run rollback on ReplicaSets owned by a Deployment (check ownerReferences).","If the annotation was lost, recreate the RS from the Deployment or restore it with `kubectl annotate rs <name> deployment.kubernetes.io/revision=<n>` before retrying."],"exampleFix":"// before: rollback attempted on an RS lacking the annotation\nrs.Annotations[\"deployment.kubernetes.io/revision\"] == \"\" -> strconv.Atoi(\"\") fails\n// after: guard before calling Rollback\nif rev, ok := rs.Annotations[\"deployment.kubernetes.io/revision\"]; !ok || rev == \"\" {\n    return fmt.Errorf(\"rs %s has no revision annotation; not deployment-managed\", rs.Name)\n}","handlingStrategy":"validation","validationCode":"rev, ok := rs.Annotations[\"deployment.kubernetes.io/revision\"]\nif !ok || rev == \"\" {\n    return fmt.Errorf(\"rs %s lacks revision annotation (not deployment-managed)\", rs.Name)\n}\nif _, err := strconv.Atoi(rev); err != nil {\n    return fmt.Errorf(\"rs %s has non-numeric revision %q\", rs.Name, rev)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only roll back ReplicaSets that have a Deployment ownerReference.","Never hand-edit the revision annotation to non-numeric values.","Restore lost annotations before retrying rollback."],"tags":["go","kubernetes","replicaset","annotation","rollback"],"backgroundTag":null,"analyzedSha":"2d3ccc6ba2ce98c3781bfc441bb3e884f072774f","analyzedAt":"2026-08-15T16:09:14.432Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}