argoproj/argo-workflows · error

cannot set output parameter '%s' because it does not use val

Error message

cannot set output parameter '%s' because it does not use valueFrom.raw or it was already set

What it means

While merging reported output parameters into the node, each target parameter must currently be an unset valueFrom.supplied parameter. If the parameter uses another valueFrom source (path, parameter, expression) or its raw value was already populated, this error is returned. It prevents overwriting a resolved value or violating the raw-parameter lifecycle (set exactly once).

Source

Thrown at workflow/util/util.go:689

					}

					// Update message
					if values.Message != "" {
						node.Message = values.Message
						nodeUpdated = true
					}

					// Update output parameters
					if len(values.OutputParameters) > 0 {
						if node.Outputs == nil {
							return true, fmt.Errorf("cannot set output parameters because node is not expecting any raw parameters")
						}
						for name, val := range values.OutputParameters {
							hit := false
							for i, param := range node.Outputs.Parameters {
								if param.Name == name {
									if param.ValueFrom == nil || param.ValueFrom.Supplied == nil {
										return true, fmt.Errorf("cannot set output parameter '%s' because it does not use valueFrom.raw or it was already set", param.Name)
									}
									node.Outputs.Parameters[i].Value = wfv1.AnyStringPtr(val)
									node.Outputs.Parameters[i].ValueFrom = nil
									nodeUpdated = true
									hit = true
									AddParamToGlobalScope(ctx, wf, node.Outputs.Parameters[i])
									break
								}
							}
							if !hit {
								return true, fmt.Errorf("node is not expecting output parameter '%s'", name)
							}
						}
					}
					wf.Status.Nodes.Set(ctx, nodeID, node)
				}
			}
		}

View on GitHub (pinned to 35bff19146)

Solutions

  1. Declare the output parameter with valueFrom.supplied (no path/parameter) when the executor is meant to supply it at runtime.
  2. Avoid duplicate output reporting: run a single executor instance per pod; restart the pod if wait/init raced.
  3. If the value should come from a file, use valueFrom.path instead of supplied and skip the runtime set.

Example fix

// before
outputs:
  parameters:
    - name: msg
      valueFrom:
        path: /tmp/msg
// after (executor sets it as raw output)
outputs:
  parameters:
    - name: msg
      valueFrom:
        supplied: {}
Defensive patterns

Strategy: validation

Validate before calling

for _, p := range node.Outputs.Parameters {
	if p.Name == name && (p.ValueFrom == nil || p.ValueFrom.Supplied == nil) {
		return fmt.Errorf("%q is not a supplied raw parameter", name)
	}
}

Type guard

func isUnsetSuppliedParam(p wfv1.Parameter) bool {
	return p.ValueFrom != nil && p.ValueFrom.Supplied != nil && p.Value == nil
}

Try / catch

if err := setOutputs(...); err != nil {
	if strings.Contains(err.Error(), "already set") {
		// duplicate report: treat as idempotent success
		return nil
	}
	return err
}

Prevention

When it happens

Trigger: WorkflowTaskResult reports a value for an output parameter whose node Outputs already has a non-supplied valueFrom (e.g. path-based) or which was already set — e.g. duplicate reports from re-executed wait containers or double pod reporting.

Common situations: Executor wait/init processes both applying the same output, retries causing duplicate PostMain output capture, or templates with both path-based and supplied valueFrom being reconciled.

Related errors


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