{"record":{"id":"2a7f9117f5e64091","repo":"argoproj/argo-workflows","slug":"failed-to-check-cronworkflow-s-stopping-conditi","errorCode":null,"errorMessage":"failed to check CronWorkflow '%s' stopping condition: %w","messagePattern":"failed to check CronWorkflow '(.+?)' stopping condition: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"workflow/cron/operator.go","lineNumber":388,"sourceCode":"\t\tcurrentWfsFulfilled[wf.UID] = fulfilledWfsPhase{\n\t\t\tfulfilled: wf.Status.Fulfilled(),\n\t\t\tphase:     wf.Status.Phase,\n\t\t}\n\t\tif !woc.cronWf.Status.HasActiveUID(wf.UID) && !wf.Status.Fulfilled() {\n\t\t\tupdated = true\n\t\t\twoc.cronWf.Status.Active = append(woc.cronWf.Status.Active, getWorkflowObjectReference(&wf, &wf))\n\t\t}\n\t}\n\n\tfor _, objectRef := range woc.cronWf.Status.Active {\n\t\tif fulfilled, found := currentWfsFulfilled[objectRef.UID]; !found || fulfilled.fulfilled {\n\t\t\tupdated = true\n\t\t\twoc.removeFromActiveList(objectRef.UID)\n\t\t\tif found && fulfilled.fulfilled {\n\t\t\t\twoc.updateWfPhaseCounter(fulfilled.phase)\n\t\t\t\tcompleted, err := woc.checkStopingCondition()\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn fmt.Errorf(\"failed to check CronWorkflow '%s' stopping condition: %w\", woc.cronWf.Name, err)\n\t\t\t\t} else if completed {\n\t\t\t\t\twoc.setAsCompleted()\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif updated {\n\t\twoc.persistCurrentWorkflowStatus(ctx)\n\t}\n\n\treturn nil\n}\n\nfunc (woc *cronWfOperationCtx) removeFromActiveList(uid types.UID) {\n\tvar newActive []corev1.ObjectReference\n\tfor _, ref := range woc.cronWf.Status.Active {\n\t\tif ref.UID != uid {","sourceCodeStart":370,"sourceCodeEnd":406,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/workflow/cron/operator.go#L370-L406","documentation":"The CronWorkflow controller failed to evaluate the StopStrategy expression while reconciling active workflows. After a child workflow completes, the operator checks whether the CronWorkflow's stop condition is fulfilled; if that evaluation returns an error, it is wrapped with the CronWorkflow name and aborts the reconciliation pass for this tick. The underlying error usually comes from expression evaluation or from fetching the environment data the expression needs.","triggerScenarios":"A CronWorkflow with spec.stopStrategy.expression set has an active child workflow that transitions to a completed phase; checkStopingCondition runs argoexpr.EvalBool on the expression and the evaluation fails (malformed expression, wrong identifier, or error building the expression environment).","commonSituations":"Typo in expression identifiers (e.g. referencing a status field that doesn't exist), invalid expression syntax after an edit, expression comparing incompatible types, or the controller failing to list/read the resources referenced in the environment.","solutions":["Validate the stopStrategy.expression syntax locally with expr-lang/argoexpr before applying the CronWorkflow (argo lint does not fully evaluate it)","Fix the expression to reference only valid identifiers available in the evaluation environment (lastScheduledTime, etc.) and use correct types","Check the wrapped cause (%w) in controller logs for the real evaluation error and address it","As a workaround, remove or correct spec.stopStrategy and use cron scheduling/pausing (spec.suspend) instead"],"exampleFix":"// before\nstopStrategy:\n  expression: lastScheduledTme.Minute() == 0  // typo + wrong field\n// after\nstopStrategy:\n  expression: cronWorkflow.lastScheduledTime.Minute() == 0","handlingStrategy":"validation","validationCode":"import \"github.com/expr-lang/expr\"\n// Before submitting, compile the stop expression\n_, err := expr.Compile(cronWf.Spec.StopStrategy.Expression,\n    expr.Env(map[string]any{\"cronWorkflow\": cronWf, \"now\": time.Now}),\n    expr.AsBool())\nif err != nil { return fmt.Errorf(\"invalid stopStrategy.expression: %w\", err) }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always compile stopStrategy expressions with expr.AsBool() in CI before applying the CronWorkflow","Keep expressions simple and reference only documented environment variables","After editing an expression, watch controller logs for the next sync tick to confirm it evaluates","Prefer spec.suspend for simple pause cases instead of complex expressions"],"tags":["kubernetes","cronworkflow","expression-evaluation","argo-workflows"],"backgroundTag":"expression-evaluation-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"}