{"record":{"id":"0f47abc823959127","repo":"argoproj/argo-workflows","slug":"unable-to-delete-successful-workflows-of-cronworkf","errorCode":null,"errorMessage":"unable to delete Successful Workflows of CronWorkflow '%s': %w","messagePattern":"unable to delete Successful Workflows of CronWorkflow '(.+?)': %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"workflow/cron/operator.go","lineNumber":437,"sourceCode":"\t\tif wf.Labels[common.LabelKeyCronWorkflow] != woc.cronWf.Name {\n\t\t\tcontinue\n\t\t}\n\t\tif wf.Status.Fulfilled() {\n\t\t\tif wf.Status.Successful() {\n\t\t\t\tsuccessfulWorkflows = append(successfulWorkflows, wf)\n\t\t\t} else {\n\t\t\t\tfailedWorkflows = append(failedWorkflows, wf)\n\t\t\t}\n\t\t}\n\t}\n\n\tworkflowsToKeep := int32(3)\n\tif woc.cronWf.Spec.SuccessfulJobsHistoryLimit != nil && *woc.cronWf.Spec.SuccessfulJobsHistoryLimit >= 0 {\n\t\tworkflowsToKeep = *woc.cronWf.Spec.SuccessfulJobsHistoryLimit\n\t}\n\terr := woc.deleteOldestWorkflows(ctx, successfulWorkflows, int(workflowsToKeep))\n\tif err != nil {\n\t\treturn fmt.Errorf(\"unable to delete Successful Workflows of CronWorkflow '%s': %w\", woc.cronWf.Name, err)\n\t}\n\n\tworkflowsToKeep = int32(1)\n\tif woc.cronWf.Spec.FailedJobsHistoryLimit != nil && *woc.cronWf.Spec.FailedJobsHistoryLimit >= 0 {\n\t\tworkflowsToKeep = *woc.cronWf.Spec.FailedJobsHistoryLimit\n\t}\n\terr = woc.deleteOldestWorkflows(ctx, failedWorkflows, int(workflowsToKeep))\n\tif err != nil {\n\t\treturn fmt.Errorf(\"unable to delete Failed Workflows of CronWorkflow '%s': %w\", woc.cronWf.Name, err)\n\t}\n\treturn nil\n}\n\nfunc (woc *cronWfOperationCtx) deleteOldestWorkflows(ctx context.Context, jobList []v1alpha1.Workflow, workflowsToKeep int) error {\n\tif workflowsToKeep >= len(jobList) {\n\t\treturn nil\n\t}\n","sourceCodeStart":419,"sourceCodeEnd":455,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/workflow/cron/operator.go#L419-L455","documentation":"The controller's history-limit enforcement could not delete surplus successful child workflows of a CronWorkflow. The operator keeps spec.successfulJobsHistoryLimit workflows (default 3) and calls deleteOldestWorkflows; any error from the Kubernetes delete/list path is wrapped with this message and surfaces in the controller's cron reconciliation error.","triggerScenarios":"deleteOldestWorkflows returns an error while pruning successfulWorkflows — e.g. a workflow Delete call fails with a non-NotFound API error, or the earlier list of successful workflows failed.","commonSituations":"RBAC: the controller's service account lacks delete permission on workflows (argoworkflows/finalizers) in the namespace; API server throttling or timeouts; a workflow stuck with finalizers preventing deletion.","solutions":["Check the wrapped error in the controller log for the underlying k8s API failure cause","Verify the workflow-controller service account has delete/update permissions on workflows in the namespace (Role/ClusterRole from the official manifests)","Look for stuck finalizers on the old workflows (kubectl get wf -o yaml) and clear the blocking finalizer","Retry — the controller re-runs enforceHistoryLimit on every cron sync tick"],"exampleFix":"// before: custom Role missing workflow deletion\nrules:\n- apiGroups: [argoproj.io]\n  resources: [workflows]\n  verbs: [get, list, watch]\n// after\nrules:\n- apiGroups: [argoproj.io]\n  resources: [workflows]\n  verbs: [get, list, watch, delete]","handlingStrategy":"retry","validationCode":"// Verify the controller can delete workflows before relying on history limits\nauthCanI, _ := exec.Command(\"kubectl\", \"auth\", \"can-i\", \"delete\",\n    \"workflows.argoproj.io\", \"-n\", ns,\n    \"--as=system:serviceaccount:argo:workflow-controller\").Output()\n// expect \"yes\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Install the controller with the official manifests so RBAC includes workflow delete verbs","Keep successfulJobsHistoryLimit >= 0 and modest to avoid mass-deletion churn","Watch for workflows stuck in Terminating (finalizers) which make pruning fail repeatedly","Re-check each sync tick — the error self-heals once the underlying API/RBAC issue is fixed"],"tags":["kubernetes","cronworkflow","rbac","history-limit","argo-workflows"],"backgroundTag":"workflow-deletion-failed","analyzedSha":"35bff19146f5a6ada77468c431f2624bd577e373","analyzedAt":"2026-09-03T19:34:35.908Z","contentChangedAt":"2026-09-03T19:34:35.908Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}