{"record":{"id":"8e44523ccfaaa870","repo":"argoproj/argo-workflows","slug":"step-group-deemed-errored-due-to-child-s-error","errorCode":null,"errorMessage":"step group deemed errored due to child %s error: %w","messagePattern":"step group deemed errored due to child (.+?) error: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"workflow/controller/steps.go","lineNumber":310,"sourceCode":"\n\t\tif stepsCtx.boundaryID == \"\" {\n\t\t\twoc.log.Warn(ctx, \"boundaryID was nil\")\n\t\t}\n\t\tvar childNode *wfv1.NodeStatus\n\t\tchildNode, err = woc.executeTemplate(ctx, childNodeName, &step, stepsCtx.tmplCtx, step.Arguments, &executeTemplateOpts{boundaryID: stepsCtx.boundaryID, onExitTemplate: stepsCtx.onExitTemplate})\n\t\tif err != nil {\n\t\t\tswitch {\n\t\t\tcase errors.Is(err, ErrDeadlineExceeded):\n\t\t\t\treturn node, nil\n\t\t\tcase errors.Is(err, ErrParallelismReached):\n\t\t\t\t// continue\n\t\t\tcase errors.Is(err, ErrMaxDepthExceeded):\n\t\t\t\t// continue\n\t\t\tcase errors.Is(err, ErrTimeout):\n\t\t\t\treturn woc.markNodePhase(ctx, node.Name, wfv1.NodeFailed, err.Error()), nil\n\t\t\tdefault:\n\t\t\t\twoc.addChildNode(ctx, sgNodeName, childNodeName)\n\t\t\t\treturn woc.markNodeError(ctx, node.Name, fmt.Errorf(\"step group deemed errored due to child %s error: %w\", childNodeName, err)), nil\n\t\t\t}\n\t\t}\n\t\tif childNode != nil {\n\t\t\tnodeSteps[childNodeName] = step\n\t\t\twoc.addChildNode(ctx, sgNodeName, childNodeName)\n\t\t}\n\t}\n\n\tnode, err = woc.wf.GetNodeByName(sgNodeName)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\t// Return if not all children completed\n\tcompleted := true\n\tfor _, childNodeID := range node.Children {\n\t\tchildNode, err := woc.wf.Status.Nodes.Get(childNodeID)\n\t\tif err != nil {\n\t\t\terrorMsg := fmt.Sprintf(\"was unable to obtain childNode for %s\", childNodeID)","sourceCodeStart":292,"sourceCodeEnd":328,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/workflow/controller/steps.go#L292-L328","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\n- name: deploy\n  template: deploy\n// after (tolerate failure)\n- name: deploy\n  template: deploy\n  continueOn:\n    error: true\n    failed: true","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if strings.Contains(err.Error(), \"step group deemed errored due to child\") {\n    childName := extractChild(err) // parse child name from message\n    // inspect wf.Status.Nodes[childName] for the root cause\n}","preventionTips":["Inspect child node status, not just the group error","Add retryStrategy to flaky steps","Use continueOn for steps allowed to fail"],"tags":["kubernetes","argo-workflows","steps","error-propagation"],"backgroundTag":"step-group-child-failure","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"}