{"record":{"id":"35a076ae36e87c23","repo":"argoproj/argo-workflows","slug":"was-unable-to-obtain-childnode-for-s","errorCode":null,"errorMessage":"was unable to obtain childNode for %s","messagePattern":"was unable to obtain childNode for (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"workflow/controller/steps.go","lineNumber":330,"sourceCode":"\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)\n\t\t\twoc.log.Error(ctx, errorMsg)\n\t\t\treturn nil, fmt.Errorf(\"%s\", errorMsg)\n\t\t}\n\t\tstep := nodeSteps[childNode.Name]\n\t\tvarkeys.StepsNodeRef.Status.Set(stepsCtx.scope.scope, string(childNode.Phase), childNode.DisplayName)\n\t\thookCompleted, err := woc.executeTmplLifeCycleHook(ctx, stepsCtx.scope, step.Hooks, childNode, stepsCtx.boundaryID, stepsCtx.tmplCtx, varkeys.StepsNodeRef, step.Name)\n\t\tif err != nil {\n\t\t\twoc.markNodeError(ctx, node.Name, err)\n\t\t}\n\t\t// Check all hooks are completed\n\t\tif !hookCompleted {\n\t\t\treturn node, nil\n\t\t}\n\n\t\tif !childNode.Fulfilled() {\n\t\t\tcompleted = false\n\t\t} else if childNode.Completed() {\n\t\t\thasOnExitNode, onExitNode, err := woc.runOnExitNode(ctx, step.GetExitHook(woc.execWf.Spec.Arguments), childNode, stepsCtx.boundaryID, stepsCtx.tmplCtx, varkeys.StepsNodeRef, step.Name, stepsCtx.scope)\n\t\t\t// see https://github.com/argoproj/argo-workflows/issues/14031,\n\t\t\t// we should return error otherwise the node will get stuck","sourceCodeStart":312,"sourceCodeEnd":348,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/workflow/controller/steps.go#L312-L348","documentation":"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.","triggerScenarios":"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.","commonSituations":"Very large workflows whose node status was compressed/offloaded and read without hydrating; manual edits to Workflow status; controller bugs dropping nodes.","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"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if strings.Contains(err.Error(), \"was unable to obtain childNode\") {\n    // hydrate workflow status via the hydrator before reading nodes, then retry\n}","preventionTips":["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"],"tags":["kubernetes","argo-workflows","steps","node-status"],"backgroundTag":"missing-child-node-status","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"}