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

  1. Confirm the parentNodeID exists via Nodes.Has() before the DFS call
  2. Re-read the Workflow from the API to get fresh node IDs after retries/resubmits
  3. 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

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


AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03). Data as JSON: /api/errors/4f1ef3448d42dcc5. Report an issue: GitHub.