{"record":{"id":"5ccc137465be3036","repo":"argoproj/argo-workflows","slug":"400-5ccc13","errorCode":"400","errorMessage":"failed to evaluate expression %q","messagePattern":"failed to evaluate expression %q","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"workflow/controller/scope.go","lineNumber":185,"sourceCode":"func (s *wfScope) resolveParameter(p *wfv1.ValueFrom) (any, bool, error) {\n\tif p == nil || (p.Parameter == \"\" && p.Expression == \"\") {\n\t\treturn \"\", false, nil\n\t}\n\tif p.Expression != \"\" {\n\t\tenv := env.GetFuncMap(s.scope.AsAnyMap())\n\t\tprogram, err := expr.Compile(p.Expression, expr.Env(env))\n\t\tif err != nil {\n\t\t\treturn nil, false, err\n\t\t}\n\t\tval, err := expr.Run(program, env)\n\t\tif err != nil {\n\t\t\treturn nil, false, err\n\t\t}\n\t\tif val == nil {\n\t\t\t// A nil result is an unhandled absent optional (e.g. a skipped node's defaultless output\n\t\t\t// referenced without `??`). Mirror the inline {{= ...}} semantics and treat it as a\n\t\t\t// resolution failure; the caller's error path applies valueFrom.default when declared.\n\t\t\treturn nil, false, errors.Errorf(errors.CodeBadRequest, \"failed to evaluate expression %q\", p.Expression)\n\t\t}\n\t\treturn val, false, nil\n\t}\n\ttag, val, err := s.resolveVar(p.Parameter)\n\t// IsSkipped is true only for a placeholder written via Key.SetSkipped (a skipped/omitted node\n\t// output with no producer default), i.e. an absent optional.\n\treturn val, s.scope.IsSkipped(tag), err\n}\n\nfunc (s *wfScope) resolveArtifact(ctx context.Context, art *wfv1.Artifact) (*wfv1.Artifact, error) {\n\tif art == nil || (art.From == \"\" && art.FromExpression == \"\") {\n\t\treturn nil, nil\n\t}\n\n\tvar err error\n\tvar val any\n\n\tif art.FromExpression != \"\" {","sourceCodeStart":167,"sourceCodeEnd":203,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/workflow/controller/scope.go#L167-L203","documentation":"resolveParameter evaluates a parameter expression against the workflow scope. When the expression evaluates to nil — an unhandled absent optional, such as a skipped node's output parameter that has no default and was referenced without the `??` operator — the controller treats it as a resolution failure with code 400, mirroring the inline {{= ...}} semantics. If the caller declared valueFrom.default, that default is applied on this error path instead of failing the step.","triggerScenarios":"Referencing {{tasks.x.outputs.parameters.y}} (or similar) in an expression when task x was skipped and its output parameter has no default, without using `??` to supply a fallback.","commonSituations":"Conditional steps (when:), failed/skipped DAG branches whose downstream steps still reference their outputs; workflows refactored to add `when` guards without updating downstream parameter references.","solutions":["Add a default to the output parameter in the producing template (valueFrom.default)","Use the null-coalescing operator in the expression, e.g. {{tasks.x.outputs.parameters.y ?? 'fallback'}}","Guard the consuming step with `when` so it only runs when the producer executed"],"exampleFix":"// before\nvalue: '{{tasks.build.outputs.parameters.version}}'\n// after\nvalue: '{{tasks.build.outputs.parameters.version ?? \"unknown\"}}'","handlingStrategy":"validation","validationCode":"// before submitting, ensure producers have defaults or consumers have fallbacks\nfor _, t := range wf.Spec.Templates {\n  for _, op := range t.Outputs.Parameters {\n    if op.ValueFrom != nil && op.ValueFrom.Default == nil {\n      // downstream refs must use `??`\n    }\n  }\n}","typeGuard":"func hasFallback(expr string) bool { return strings.Contains(expr, \"??\") }","tryCatchPattern":"if resolved, ok, err := resolveParameter(p); err != nil || !ok {\n  if p.Value != nil { useDefault(p) } else { return fmt.Errorf(\"expression %q unresolved: %w\", p.Expression, err) }\n}","preventionTips":["Always set valueFrom.default on output parameters of templates that can be skipped","Use `??` when referencing outputs of conditional tasks","Guard dependent steps with `when` conditions"],"tags":["kubernetes","workflow-parameters","expression-evaluation","argo-workflows"],"backgroundTag":"missing-expression-value","analyzedSha":"35bff19146f5a6ada77468c431f2624bd577e373","analyzedAt":"2026-09-03T19:34:35.908Z","contentChangedAt":"2026-09-03T19:34:35.908Z","schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}