argoproj/argo-workflows · error
step group deemed errored due to child %s error: %w
Error message
step group deemed errored due to child %s error: %w
What it means
When a child step of a step group finishes in an error state that is not retryable/skippable (and not max-depth or timeout handled specially), the whole step group node is marked Error with this message wrapping the child's name and error. It propagates the child failure to the group boundary.
Source
Thrown at workflow/controller/steps.go:310
if stepsCtx.boundaryID == "" {
woc.log.Warn(ctx, "boundaryID was nil")
}
var childNode *wfv1.NodeStatus
childNode, err = woc.executeTemplate(ctx, childNodeName, &step, stepsCtx.tmplCtx, step.Arguments, &executeTemplateOpts{boundaryID: stepsCtx.boundaryID, onExitTemplate: stepsCtx.onExitTemplate})
if err != nil {
switch {
case errors.Is(err, ErrDeadlineExceeded):
return node, nil
case errors.Is(err, ErrParallelismReached):
// continue
case errors.Is(err, ErrMaxDepthExceeded):
// continue
case errors.Is(err, ErrTimeout):
return woc.markNodePhase(ctx, node.Name, wfv1.NodeFailed, err.Error()), nil
default:
woc.addChildNode(ctx, sgNodeName, childNodeName)
return woc.markNodeError(ctx, node.Name, fmt.Errorf("step group deemed errored due to child %s error: %w", childNodeName, err)), nil
}
}
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)View on GitHub (pinned to 35bff19146)
Solutions
- Inspect the child node named in the message for its real failure (message, exit code, logs)
- Fix the failing step's template (image, command, resources)
- Add retryStrategy or continueOn to tolerate expected child failures
Example fix
// before
- name: deploy
template: deploy
// after (tolerate failure)
- name: deploy
template: deploy
continueOn:
error: true
failed: true Defensive patterns
Strategy: try-catch
Try / catch
if strings.Contains(err.Error(), "step group deemed errored due to child") {
childName := extractChild(err) // parse child name from message
// inspect wf.Status.Nodes[childName] for the root cause
} Prevention
- Inspect child node status, not just the group error
- Add retryStrategy to flaky steps
- Use continueOn for steps allowed to fail
When it happens
Trigger: executeStepGroup processes a child node whose phase is Error/Failure and the error matches none of the special cases (ErrMaxDepthExceeded, ErrTimeout, retry logic), so markNodeError is called on the group node.
Common situations: A step inside a parallel group fails (bad image, OOM, script exit code); user sees the group-level error and must inspect children to find the root cause.
Related errors
- was unable to obtain childNode for %s
- 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/8e44523ccfaaa870.
Report an issue: GitHub.