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.ErrorView on GitHub (pinned to 35bff19146)
Solutions
- Check the node in `argo get <wf>` / kubectl: confirm whether it truly has outputs.artifacts in its status.
- 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.
- 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.
- Upgrade the controller — this can be a symptom of status-offload bugs fixed in newer releases; check the changelog.
- 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
- Scope artifactGC so nodes without outputs are not reported (per-template artifactGC strategy).
- Declare outputs explicitly in templates whose artifacts need GC.
- Watch for status truncation on large workflows — outputs can be dropped under size limits.
- Pin controller versions; avoid mixing old GC tasks with new workflow status.
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
- node named %q returned by WorkflowArtifactGCTask %q wasn't f
- can't process Artifact GC Strategy %s: node ID %q not found
- can't process Artifact GC Strategy %s: node %+v has an unnam
- can't process Artifact GC Strategy %s: template name %q belo
- can't find podInfo for podName %q
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/be994714c8ca140b.
Report an issue: GitHub.