argoproj/argo-workflows · error

failed to check CronWorkflow '%s' stopping condition: %w

Error message

failed to check CronWorkflow '%s' stopping condition: %w

What it means

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.

Source

Thrown at workflow/cron/operator.go:388

		currentWfsFulfilled[wf.UID] = fulfilledWfsPhase{
			fulfilled: wf.Status.Fulfilled(),
			phase:     wf.Status.Phase,
		}
		if !woc.cronWf.Status.HasActiveUID(wf.UID) && !wf.Status.Fulfilled() {
			updated = true
			woc.cronWf.Status.Active = append(woc.cronWf.Status.Active, getWorkflowObjectReference(&wf, &wf))
		}
	}

	for _, objectRef := range woc.cronWf.Status.Active {
		if fulfilled, found := currentWfsFulfilled[objectRef.UID]; !found || fulfilled.fulfilled {
			updated = true
			woc.removeFromActiveList(objectRef.UID)
			if found && fulfilled.fulfilled {
				woc.updateWfPhaseCounter(fulfilled.phase)
				completed, err := woc.checkStopingCondition()
				if err != nil {
					return fmt.Errorf("failed to check CronWorkflow '%s' stopping condition: %w", woc.cronWf.Name, err)
				} else if completed {
					woc.setAsCompleted()
				}
			}
		}
	}

	if updated {
		woc.persistCurrentWorkflowStatus(ctx)
	}

	return nil
}

func (woc *cronWfOperationCtx) removeFromActiveList(uid types.UID) {
	var newActive []corev1.ObjectReference
	for _, ref := range woc.cronWf.Status.Active {
		if ref.UID != uid {

View on GitHub (pinned to 35bff19146)

Solutions

  1. Validate the stopStrategy.expression syntax locally with expr-lang/argoexpr before applying the CronWorkflow (argo lint does not fully evaluate it)
  2. Fix the expression to reference only valid identifiers available in the evaluation environment (lastScheduledTime, etc.) and use correct types
  3. Check the wrapped cause (%w) in controller logs for the real evaluation error and address it
  4. As a workaround, remove or correct spec.stopStrategy and use cron scheduling/pausing (spec.suspend) instead

Example fix

// before
stopStrategy:
  expression: lastScheduledTme.Minute() == 0  // typo + wrong field
// after
stopStrategy:
  expression: cronWorkflow.lastScheduledTime.Minute() == 0
Defensive patterns

Strategy: validation

Validate before calling

import "github.com/expr-lang/expr"
// Before submitting, compile the stop expression
_, err := expr.Compile(cronWf.Spec.StopStrategy.Expression,
    expr.Env(map[string]any{"cronWorkflow": cronWf, "now": time.Now}),
    expr.AsBool())
if err != nil { return fmt.Errorf("invalid stopStrategy.expression: %w", err) }

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03). Data as JSON: /api/errors/2a7f9117f5e64091. Report an issue: GitHub.