argoproj/argo-workflows · error

failed to evaluate expression: %s is missing

Error message

failed to evaluate expression: %s is missing

What it means

expressionReplaceStrict determined that the expression references variables missing from env; the message (built from missingVars) names the missing identifier(s). This is the strict-mode rejection: unlike allowUnresolved paths, the unresolved variable is a terminal error here.

Source

Thrown at util/template/expression_template.go:92

func expressionReplaceStrict(ctx context.Context, w io.Writer, expression string, env map[string]any, strictRegex *regexp.Regexp) (int, error) {
	// The template is JSON-marshaled. This JSON-unmarshals the expression to undo any character escapes.
	var unmarshalledExpression string
	err := json.Unmarshal(fmt.Appendf(nil, `"%s"`, expression), &unmarshalledExpression)
	if err != nil {
		// If we can't unmarshal, we can't parse. Fallback to expressionReplaceCore to handle it (likely error).
		return expressionReplaceCore(ctx, w, expression, env, false)
	}

	missingIdentifiers, err := missingVarsInEnv(unmarshalledExpression, env)
	if err != nil {
		// If we can't parse, we can't check variables. Fallback to expressionReplaceCore(false) to report syntax error.
		return expressionReplaceCore(ctx, w, expression, env, false)
	}

	for _, id := range missingIdentifiers {
		if strictRegex != nil && strictRegex.MatchString(id) {
			return 0, fmt.Errorf("failed to evaluate expression: %s is missing", id)
		}
	}

	// If we have missing identifiers but they are NOT strict, we allow unresolved.
	// If we have NO missing identifiers, we enforce resolution (to catch runtime errors),
	// unless the caller allows unresolved (strictRegex == nil), in which case runtime
	// failures are tolerated and the expression is left unresolved for later evaluation.
	allowUnresolved := len(missingIdentifiers) > 0 || strictRegex == nil
	return expressionReplaceCore(ctx, w, expression, env, allowUnresolved)
}

type identifierVisitor struct {
	identifiers []string
	seen        map[string]bool
	guarded     map[ast.Node]bool
}

func (v *identifierVisitor) Visit(node *ast.Node) {

View on GitHub (pinned to 35bff19146)

Solutions

  1. Supply the missing variable (e.g. define the parameter or ensure the referenced node output exists)
  2. Check spelling of identifiers inside the {{= ... }} expression
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at util/template/expression_template.go:92 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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