argoproj/argo-workflows · error
could not find %s in nodes when searching for nested childre
Error message
could not find %s in nodes when searching for nested children
What it means
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.
Source
Thrown at pkg/apis/workflow/v1alpha1/workflow_types.go:2131
childNodes := make(Nodes)
parentNode, ok := n[parentNodeID]
if !ok {
return childNodes
}
for _, childID := range parentNode.Children {
if childNode, ok := n[childID]; ok {
childNodes[childID] = childNode
}
}
return childNodes
}
// NestedChildrenStatus takes in a nodeID and returns all its children, this involves a tree search using DFS.
// This is needed to mark all children nodes as failed for example.
func (n Nodes) NestedChildrenStatus(parentNodeID string) ([]NodeStatus, error) {
parentNode, ok := n[parentNodeID]
if !ok {
return nil, fmt.Errorf("could not find %s in nodes when searching for nested children", parentNodeID)
}
children := []NodeStatus{}
toexplore := []NodeStatus{parentNode}
for len(toexplore) > 0 {
childNode := toexplore[0]
toexplore = toexplore[1:]
for _, nodeID := range childNode.Children {
toexplore = append(toexplore, n[nodeID])
}
if childNode.Name == parentNode.Name {
continue
}
children = append(children, childNode)
}
View on GitHub (pinned to 35bff19146)
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
Example fix
// before
children, err := wf.Status.Nodes.NestedChildrenStatus(staleID)
// after
if !wf.Status.Nodes.Has(nodeID) {
return nil // nothing to do; node no longer exists
}
children, err := wf.Status.Nodes.NestedChildrenStatus(nodeID) Defensive patterns
Strategy: type-guard
Validate before calling
if !wf.Status.Nodes.Has(parentNodeID) {
return nil, fmt.Errorf("parent node %s not present; skip subtree walk", parentNodeID)
} Type guard
func (n Nodes) canWalk(parentNodeID string) bool {
_, ok := n[parentNodeID]
return ok
} Try / catch
children, err := wf.Status.Nodes.NestedChildrenStatus(parentNodeID)
if err != nil {
if strings.Contains(err.Error(), "could not find") {
return nil // parent vanished (retry/resubmit); nothing to mark
}
return err
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- key was not found for %s
- could not get node status for node ID %s
- can't process Artifact GC Strategy %s: node ID %q not found
- can't process Artifact GC Strategy %s: node %+v has an unnam
- node named %q returned by WorkflowArtifactGCTask %q wasn't f
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/4f1ef3448d42dcc5.
Report an issue: GitHub.