argoproj/argo-workflows · error
was unable to obtain childNode for %s
Error message
was unable to obtain childNode for %s
What it means
While evaluating a completed step group, the controller iterates node.Children to fetch each child node from Status.Nodes. If a child ID is missing from status (inconsistent/compressed/offloaded state), it logs and returns this error, aborting the step-group evaluation.
Source
Thrown at workflow/controller/steps.go:330
}
if childNode != nil {
nodeSteps[childNodeName] = step
woc.addChildNode(ctx, sgNodeName, childNodeName)
}
}
node, err = woc.wf.GetNodeByName(sgNodeName)
if err != nil {
return nil, err
}
// Return if not all children completed
completed := true
for _, childNodeID := range node.Children {
childNode, err := woc.wf.Status.Nodes.Get(childNodeID)
if err != nil {
errorMsg := fmt.Sprintf("was unable to obtain childNode for %s", childNodeID)
woc.log.Error(ctx, errorMsg)
return nil, fmt.Errorf("%s", errorMsg)
}
step := nodeSteps[childNode.Name]
varkeys.StepsNodeRef.Status.Set(stepsCtx.scope.scope, string(childNode.Phase), childNode.DisplayName)
hookCompleted, err := woc.executeTmplLifeCycleHook(ctx, stepsCtx.scope, step.Hooks, childNode, stepsCtx.boundaryID, stepsCtx.tmplCtx, varkeys.StepsNodeRef, step.Name)
if err != nil {
woc.markNodeError(ctx, node.Name, err)
}
// Check all hooks are completed
if !hookCompleted {
return node, nil
}
if !childNode.Fulfilled() {
completed = false
} else if childNode.Completed() {
hasOnExitNode, onExitNode, err := woc.runOnExitNode(ctx, step.GetExitHook(woc.execWf.Spec.Arguments), childNode, stepsCtx.boundaryID, stepsCtx.tmplCtx, varkeys.StepsNodeRef, step.Name, stepsCtx.scope)
// see https://github.com/argoproj/argo-workflows/issues/14031,
// we should return error otherwise the node will get stuckView on GitHub (pinned to 35bff19146)
Solutions
- Re-run/retry the workflow to rebuild consistent status
- Check whether the workflow status exceeds size limits (offloaded to DB) and ensure the reader hydrates via the hydrator
- Avoid manual kubectl edits of status.nodes; report corruption to Argo maintainers
Defensive patterns
Strategy: try-catch
Try / catch
if strings.Contains(err.Error(), "was unable to obtain childNode") {
// hydrate workflow status via the hydrator before reading nodes, then retry
} Prevention
- Avoid manual edits to status.nodes
- Keep workflows under node-status size limits to avoid offloading issues
- Use the official API/hydrator when reading large workflows
When it happens
Trigger: A child node ID recorded on the step-group node is not present in wf.Status.Nodes during executeStepGroup — e.g. status was truncated/offloaded without hydration, or nodes were corrupted/deleted.
Common situations: Very large workflows whose node status was compressed/offloaded and read without hydrating; manual edits to Workflow status; controller bugs dropping nodes.
Related errors
- step group deemed errored due to child %s error: %w
- unable to resolve references: %w
- failed to resolve references: %w
- unable to parse argo variable: %w
- failed to read container args file %s: %w
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/35a076ae36e87c23.
Report an issue: GitHub.