{"record":{"id":"be994714c8ca140b","repo":"argoproj/argo-workflows","slug":"node-named-q-returned-by-workflowartifactgctask-be9947","errorCode":null,"errorMessage":"node named %q returned by WorkflowArtifactGCTask %q doesn't seem to have Outputs in Workflow Status","messagePattern":"node named %q returned by WorkflowArtifactGCTask %q doesn't seem to have Outputs in Workflow Status","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"workflow/controller/artifact_gc.go","lineNumber":690,"sourceCode":"\t}\n\treturn nil\n}\n\n// process the Status in the WorkflowArtifactGCTask which was completed and reflect it in Workflow Status; then delete the Task CRD Object\n// return true if all artifacts succeeded, else false\nfunc (woc *wfOperationCtx) processCompletedWorkflowArtifactGCTask(ctx context.Context, artifactGCTask *wfv1.WorkflowArtifactGCTask, strategy wfv1.ArtifactGCStrategy) (bool, error) {\n\twoc.log.WithField(\"name\", artifactGCTask.Name).Debug(ctx, \"processing WorkflowArtifactGCTask\")\n\n\tfoundGCFailure := false\n\tfor nodeName, nodeResult := range artifactGCTask.Status.ArtifactResultsByNode {\n\t\t// find this node result in the Workflow Status\n\t\twfNode, err := woc.wf.Status.Nodes.Get(nodeName)\n\t\tif err != nil {\n\t\t\twoc.log.WithField(\"node\", nodeName).WithError(err).Error(ctx, \"Was unable to obtain node for\")\n\t\t\treturn false, fmt.Errorf(\"node named %q returned by WorkflowArtifactGCTask %q wasn't found in Workflow %q Status\", nodeName, artifactGCTask.Name, woc.wf.Name)\n\t\t}\n\t\tif wfNode.Outputs == nil {\n\t\t\treturn false, fmt.Errorf(\"node named %q returned by WorkflowArtifactGCTask %q doesn't seem to have Outputs in Workflow Status\", nodeName, artifactGCTask.Name)\n\t\t}\n\t\tfor i, wfArtifact := range wfNode.Outputs.Artifacts {\n\t\t\t// find artifact in the WorkflowArtifactGCTask Status\n\t\t\tartifactResult, foundArt := nodeResult.ArtifactResults[wfArtifact.Name]\n\t\t\tif !foundArt {\n\t\t\t\t// could be in a different WorkflowArtifactGCTask\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\twfNode.Outputs.Artifacts[i].Deleted = artifactResult.Success\n\t\t\twoc.wf.Status.Nodes.Set(ctx, nodeName, *wfNode)\n\n\t\t\tif artifactResult.Error != nil {\n\t\t\t\twoc.addArtGCCondition(fmt.Sprintf(\"%s (artifactGCTask: %s)\", *artifactResult.Error, artifactGCTask.Name))\n\t\t\t\t// issue an Event if there was an error - just do this once to prevent flooding the system with Events\n\t\t\t\tif !foundGCFailure {\n\t\t\t\t\tfoundGCFailure = true\n\t\t\t\t\tgcFailureMsg := *artifactResult.Error","sourceCodeStart":672,"sourceCodeEnd":708,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/workflow/controller/artifact_gc.go#L672-L708","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\nspec:\n  artifactGC:\n    strategy: OnWorkflowCompletion\n# after — scope GC to workflow-level artifacts only\nspec:\n  artifactGC:\n    strategy: OnWorkflowCompletion\n  templates:\n    - name: main\n      artifactGC:\n        strategy: Never","handlingStrategy":"validation","validationCode":"const node = wf.status?.nodes?.[nodeName];\nif (!node) throw new Error('node missing');\nif (!node.outputs || !Array.isArray(node.outputs.artifacts)) console.warn(`node ${nodeName} has no outputs; GC results cannot be merged`);","typeGuard":"function nodeHasOutputs(node) {\n  return Boolean(node && node.outputs && Array.isArray(node.outputs.artifacts));\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["kubernetes","artifact-gc","workflow-status"],"backgroundTag":"node-not-found-in-workflow-status","analyzedSha":"35bff19146f5a6ada77468c431f2624bd577e373","analyzedAt":"2026-09-03T19:34:35.908Z","contentChangedAt":"2026-09-03T19:34:35.908Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}