argoproj/argo-workflows · error

node named %q returned by WorkflowArtifactGCTask %q doesn't

Error message

node named %q returned by WorkflowArtifactGCTask %q doesn't seem to have Outputs in Workflow Status

What it means

While merging a completed WorkflowArtifactGCTask's results back into the Workflow, the controller found the node in Status.Nodes but the node has no Outputs section. Artifact GC results are keyed by output artifact names taken from the node's Outputs.Artifacts, so a node without Outputs cannot have its artifacts matched and GC results cannot be applied.

Source

Thrown at workflow/controller/artifact_gc.go:690

	}
	return nil
}

// process the Status in the WorkflowArtifactGCTask which was completed and reflect it in Workflow Status; then delete the Task CRD Object
// return true if all artifacts succeeded, else false
func (woc *wfOperationCtx) processCompletedWorkflowArtifactGCTask(ctx context.Context, artifactGCTask *wfv1.WorkflowArtifactGCTask, strategy wfv1.ArtifactGCStrategy) (bool, error) {
	woc.log.WithField("name", artifactGCTask.Name).Debug(ctx, "processing WorkflowArtifactGCTask")

	foundGCFailure := false
	for nodeName, nodeResult := range artifactGCTask.Status.ArtifactResultsByNode {
		// find this node result in the Workflow Status
		wfNode, err := woc.wf.Status.Nodes.Get(nodeName)
		if err != nil {
			woc.log.WithField("node", nodeName).WithError(err).Error(ctx, "Was unable to obtain node for")
			return false, fmt.Errorf("node named %q returned by WorkflowArtifactGCTask %q wasn't found in Workflow %q Status", nodeName, artifactGCTask.Name, woc.wf.Name)
		}
		if wfNode.Outputs == nil {
			return false, fmt.Errorf("node named %q returned by WorkflowArtifactGCTask %q doesn't seem to have Outputs in Workflow Status", nodeName, artifactGCTask.Name)
		}
		for i, wfArtifact := range wfNode.Outputs.Artifacts {
			// find artifact in the WorkflowArtifactGCTask Status
			artifactResult, foundArt := nodeResult.ArtifactResults[wfArtifact.Name]
			if !foundArt {
				// could be in a different WorkflowArtifactGCTask
				continue
			}

			wfNode.Outputs.Artifacts[i].Deleted = artifactResult.Success
			woc.wf.Status.Nodes.Set(ctx, nodeName, *wfNode)

			if artifactResult.Error != nil {
				woc.addArtGCCondition(fmt.Sprintf("%s (artifactGCTask: %s)", *artifactResult.Error, artifactGCTask.Name))
				// issue an Event if there was an error - just do this once to prevent flooding the system with Events
				if !foundGCFailure {
					foundGCFailure = true
					gcFailureMsg := *artifactResult.Error

View on GitHub (pinned to 35bff19146)

Solutions

  1. Check the node in `argo get <wf>` / kubectl: confirm whether it truly has outputs.artifacts in its status.
  2. If the node legitimately has no outputs, this indicates the GC task should not have included it — verify artifactGCScope (e.g. set to 'OnWorkflowCompletion' with correct scope) and delete the stale GC task to force re-reconciliation.
  3. If outputs were lost due to status size limits, reduce node status size (fewer/larger offloaded fields) or raise the offload threshold, then re-run.
  4. Upgrade the controller — this can be a symptom of status-offload bugs fixed in newer releases; check the changelog.
  5. Work around by re-annotating: if the node should have outputs, fix the template so outputs are declared.

Example fix

# before
spec:
  artifactGC:
    strategy: OnWorkflowCompletion
# after — scope GC to workflow-level artifacts only
spec:
  artifactGC:
    strategy: OnWorkflowCompletion
  templates:
    - name: main
      artifactGC:
        strategy: Never
Defensive patterns

Strategy: validation

Validate before calling

const node = wf.status?.nodes?.[nodeName];
if (!node) throw new Error('node missing');
if (!node.outputs || !Array.isArray(node.outputs.artifacts)) console.warn(`node ${nodeName} has no outputs; GC results cannot be merged`);

Type guard

function nodeHasOutputs(node) {
  return Boolean(node && node.outputs && Array.isArray(node.outputs.artifacts));
}

Prevention

When it happens

Trigger: The GC task reports a node whose Status.Nodes entry has wfNode.Outputs == nil — e.g. the node is a container-set/steps/DAG group node that never declared output artifacts, but its ID ended up in ArtifactResultsByNode, or outputs were dropped during status compression/offloading.

Common situations: artifactGC configured at workflow level so the GC pod reports results for every node including ones without outputs; large workflows where output artifacts were truncated from status; templates where outputs are conditional and never produced.

Related errors


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