{"record":{"id":"ff0017f35c173dcd","repo":"argoproj/argo-workflows","slug":"node-named-q-returned-by-workflowartifactgctask","errorCode":null,"errorMessage":"node named %q returned by WorkflowArtifactGCTask %q wasn't found in Workflow %q Status","messagePattern":"node named %q returned by WorkflowArtifactGCTask %q wasn't found in Workflow %q Status","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"workflow/controller/artifact_gc.go","lineNumber":687,"sourceCode":"\t\t\t\twoc.log.WithField(\"name\", task.Name).WithError(err).Error(ctx, \"error deleting WorkflowArtifactGCTask\")\n\t\t\t}\n\t\t}\n\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","sourceCodeStart":669,"sourceCodeEnd":705,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/workflow/controller/artifact_gc.go#L669-L705","documentation":"During artifact garbage collection, the controller reconciles a completed WorkflowArtifactGCTask pod by matching each node reported in the task's ArtifactResultsByNode against the Workflow's Status.Nodes. This error is returned when a node name recorded in the GC task's status cannot be found in the Workflow status — meaning the GC pod reported results for a node the Workflow no longer tracks.","triggerScenarios":"A WorkflowArtifactGCTask pod completes and its Status.ArtifactResultsByNode contains a nodeName that is absent from wf.Status.Nodes — e.g. the node was pruned, the status was offloaded/truncated and lost that node, or the GC task references a stale nodeID from a retried/deleted workflow version.","commonSituations":"Running workflows with artifactGC enabled where the workflow status was compressed/offloaded and node entries dropped; resubmitting or retrying workflows so an old artifact-gc pod reconciles against a new workflow; manually editing or trimming Status.Nodes; upgrading across versions with large node status.","solutions":["Inspect the WorkflowArtifactGCTask pod status (kubectl get wfartgc -o yaml) and compare its ArtifactResultsByNode keys with `argo get <wf>` node names to find the stale node.","Check whether workflow status offloading is active (workflow-controller-configmap nodeStatusOffload) and whether hydration lost nodes; re-run the GC reconciliation after full hydration.","Delete the stale WorkflowArtifactGCTask resource so the controller recreates it with current node references.","If this happened after retry/resubmit, ensure the retried workflow's artifactGCScope/strategy matches and old GC tasks from the original run are deleted.","Report with controller logs (node=<name>) if node status legitimately contains the node — may indicate a hydrator bug."],"exampleFix":"// before: reconciling old GC task against retried workflow\nkubectl delete wfartgctask <stale-gc-task-name>\n// after: GC task recreated against current nodes","handlingStrategy":"validation","validationCode":"const nodes = wf.status?.nodes || {};\nconst gcTask = await k8s.getNamespacedCustomObject('argoproj.io','v1alpha1',ns,'workflowartifactgctasks',name);\nconst missing = Object.keys(gcTask.status?.artifactResultsByNode || {}).filter(n => !(n in nodes));\nif (missing.length) throw new Error(`GC task references missing nodes: ${missing.join(',')}`);","typeGuard":"function hasNode(wf, nodeName) {\n  return Boolean(wf.status && wf.status.nodes && wf.status.nodes[nodeName]);\n}","tryCatchPattern":null,"preventionTips":["Before deleting/pruning workflow status nodes, check no WorkflowArtifactGCTask references them.","Avoid manual edits to Status.Nodes on workflows with artifactGC enabled.","Keep status offloading/hydration healthy — watch for hydrator errors in controller logs.","After retry/resubmit, delete GC tasks from the original run."],"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"}