argoproj/argo-workflows · error

raw output parameter '%s' has not been set and does not have

Error message

raw output parameter '%s' has not been set and does not have a default value

What it means

OverrideOutputParametersWithDefault finalizes a node's output parameters: for parameters declared with valueFrom.supplied, it substitutes the declared default. If a supplied parameter has no valueFrom.default and hasn't been set, the function errors because the raw parameter would otherwise have no value. This guards invariants when a producer node exits without emitting its raw output.

Source

Thrown at workflow/util/util.go:510

			_, err := wfIf.Update(ctx, wf, metav1.UpdateOptions{})
			if apierr.IsConflict(err) {
				return false, nil
			}
			return !errorsutil.IsTransientErr(ctx, err), err
		}
		return true, nil
	})
	return err
}

func OverrideOutputParametersWithDefault(outputs *wfv1.Outputs) error {
	if outputs == nil {
		return nil
	}
	for i, param := range outputs.Parameters {
		if param.ValueFrom != nil && param.ValueFrom.Supplied != nil {
			if param.ValueFrom.Default == nil {
				return fmt.Errorf("raw output parameter '%s' has not been set and does not have a default value", param.Name)
			}
			outputs.Parameters[i].Value = param.ValueFrom.Default
			outputs.Parameters[i].ValueFrom = nil
		}
	}
	return nil
}

// ResumeWorkflow resumes a workflow by setting spec.suspend to nil and any suspended nodes to Successful.
// Retries conflict errors
func ResumeWorkflow(ctx context.Context, wfIf v1alpha1.WorkflowInterface, hydrator hydrator.Interface, workflowName string, nodeFieldSelector string) error {
	uiMsg := ""
	uim := creator.UserInfoMap(ctx)
	if uim != nil {
		uiMsg = fmt.Sprintf("Resumed by: %v", uim)
	}
	if len(nodeFieldSelector) > 0 {
		return updateSuspendedNode(ctx, wfIf, hydrator, workflowName, nodeFieldSelector, SetOperationValues{Phase: wfv1.NodeSucceeded, Message: uiMsg}, creator.ActionResume)

View on GitHub (pinned to 35bff19146)

Solutions

  1. Add a valueFrom.default to every valueFrom.supplied output parameter so unset values fall back cleanly.
  2. Ensure the producing step actually emits the parameter (script writes stdout, suspend gets argo resume/resubmit with values).
  3. Inspect the workflow nodes to find which step failed to produce the raw output before the override ran.

Example fix

// before
outputs:
  parameters:
    - name: out
      valueFrom:
        supplied: {}
// after
outputs:
  parameters:
    - name: out
      valueFrom:
        default: "fallback"
        supplied: {}
Defensive patterns

Strategy: validation

Validate before calling

for _, p := range outputs.Parameters {
	if p.ValueFrom != nil && p.ValueFrom.Supplied != nil && p.ValueFrom.Default == nil {
		return fmt.Errorf("raw output parameter %q lacks a default", p.Name)
	}
}

Type guard

func hasDefault(p wfv1.Parameter) bool {
	return p.ValueFrom == nil || p.ValueFrom.Supplied == nil || p.ValueFrom.Default != nil
}

Try / catch

if err := util.OverrideOutputParametersWithDefault(wf.Status.Nodes[nodeID].Outputs); err != nil {
	logger.Warn(ctx, "unset raw output parameter: "+err.Error())
	return err
}

Prevention

When it happens

Trigger: A step/suspend node declares outputs.parameters with valueFrom.supplied but no default, the executor never sets the value (step failed to produce output or container exited before capture), and the output-override path is then applied.

Common situations: Suspend nodes whose value is never set via argo resume/set, script steps that crash before writing the output file, or templates where outputs were declared but the producing logic was removed.

Related errors


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