{"record":{"id":"4f1ef3448d42dcc5","repo":"argoproj/argo-workflows","slug":"could-not-find-s-in-nodes-when-searching-for-nest","errorCode":null,"errorMessage":"could not find %s in nodes when searching for nested children","messagePattern":"could not find (.+?) in nodes when searching for nested children","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/apis/workflow/v1alpha1/workflow_types.go","lineNumber":2131,"sourceCode":"\tchildNodes := make(Nodes)\n\tparentNode, ok := n[parentNodeID]\n\tif !ok {\n\t\treturn childNodes\n\t}\n\tfor _, childID := range parentNode.Children {\n\t\tif childNode, ok := n[childID]; ok {\n\t\t\tchildNodes[childID] = childNode\n\t\t}\n\t}\n\treturn childNodes\n}\n\n// NestedChildrenStatus takes in a nodeID and returns all its children, this involves a tree search using DFS.\n// This is needed to mark all children nodes as failed for example.\nfunc (n Nodes) NestedChildrenStatus(parentNodeID string) ([]NodeStatus, error) {\n\tparentNode, ok := n[parentNodeID]\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"could not find %s in nodes when searching for nested children\", parentNodeID)\n\t}\n\n\tchildren := []NodeStatus{}\n\ttoexplore := []NodeStatus{parentNode}\n\n\tfor len(toexplore) > 0 {\n\t\tchildNode := toexplore[0]\n\t\ttoexplore = toexplore[1:]\n\t\tfor _, nodeID := range childNode.Children {\n\t\t\ttoexplore = append(toexplore, n[nodeID])\n\t\t}\n\n\t\tif childNode.Name == parentNode.Name {\n\t\t\tcontinue\n\t\t}\n\t\tchildren = append(children, childNode)\n\t}\n","sourceCodeStart":2113,"sourceCodeEnd":2149,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/pkg/apis/workflow/v1alpha1/workflow_types.go#L2113-L2149","documentation":"Nodes.NestedChildrenStatus does a DFS from a parent node ID to collect all nested children (used e.g. to mark a whole subtree failed). If the given parentNodeID is not a key in the Nodes map, the parent cannot be found and this error is returned.","triggerScenarios":"Calling NestedChildrenStatus(parentNodeID) with an ID absent from wf.Status.Nodes — e.g. after the workflow object was retried/resubmitted (node IDs regenerated) or the ID came from a different workflow.","commonSituations":"Custom controllers caching node IDs across workflow retries; event handlers processing a node ID from a deleted/recreated workflow; mixing up pod names with node IDs.","solutions":["Confirm the parentNodeID exists via Nodes.Has() before the DFS call","Re-read the Workflow from the API to get fresh node IDs after retries/resubmits","Use node IDs from the same Workflow object's Status.Nodes rather than cached or cross-object IDs"],"exampleFix":"// before\nchildren, err := wf.Status.Nodes.NestedChildrenStatus(staleID)\n// after\nif !wf.Status.Nodes.Has(nodeID) {\n    return nil // nothing to do; node no longer exists\n}\nchildren, err := wf.Status.Nodes.NestedChildrenStatus(nodeID)","handlingStrategy":"type-guard","validationCode":"if !wf.Status.Nodes.Has(parentNodeID) {\n    return nil, fmt.Errorf(\"parent node %s not present; skip subtree walk\", parentNodeID)\n}","typeGuard":"func (n Nodes) canWalk(parentNodeID string) bool {\n    _, ok := n[parentNodeID]\n    return ok\n}","tryCatchPattern":"children, err := wf.Status.Nodes.NestedChildrenStatus(parentNodeID)\nif err != nil {\n    if strings.Contains(err.Error(), \"could not find\") {\n        return nil // parent vanished (retry/resubmit); nothing to mark\n    }\n    return err\n}","preventionTips":["Invalidate cached node IDs after workflow retry/resubmit","Use node IDs only from the same Workflow object's Status.Nodes","Treat missing parents as a normal race and no-op rather than a failure"],"tags":["workflow-status","nodes","dfs","node-not-found"],"backgroundTag":"node-not-found","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"}