{"record":{"id":"3d3266206639da2c","repo":"argoproj/argo-workflows","slug":"failed-to-substitute-the-podspecpatch-variables","errorCode":null,"errorMessage":"Failed to substitute the PodSpecPatch variables","messagePattern":"Failed to substitute the PodSpecPatch variables","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"workflow/controller/workflowpod.go","lineNumber":318,"sourceCode":"\tpodSpecPatches := []string{}\n\tlocalParams := make(map[string]string)\n\tif tmpl.IsPodType() {\n\t\tlocalParams[varkeys.PodName.Template()] = pod.Name\n\t}\n\ttoProcess := []string{}\n\tif pb.in.execWfSpec.HasPodSpecPatch() {\n\t\ttoProcess = append(toProcess, pb.in.execWfSpec.PodSpecPatch)\n\t}\n\tif tmpl.HasPodSpecPatch() {\n\t\ttoProcess = append(toProcess, tmpl.PodSpecPatch)\n\t}\n\n\tfor _, patch := range toProcess {\n\t\tnewTmpl := tmpl.DeepCopy()\n\t\tnewTmpl.PodSpecPatch = patch\n\t\tprocessedTmpl, err := common.ProcessArgs(ctx, newTmpl, &wfv1.Arguments{}, pb.in.globalParams, localParams, false, pb.in.namespace, pb.in.configMapIndexer)\n\t\tif err != nil {\n\t\t\treturn nil, errors.Wrap(err, \"\", \"Failed to substitute the PodSpecPatch variables\")\n\t\t}\n\t\tpodSpecPatches = append(podSpecPatches, processedTmpl.PodSpecPatch)\n\t}\n\treturn podSpecPatches, nil\n}\n\n// podBuildResult is the output of the pure pod builder. It carries the\n// constructed pod plus everything submitPod needs to apply as side effects.\n// build performs ZERO k8s creates and ZERO status mutations: it only fills in\n// this struct. submitPod consumes it and performs the impure operations in a\n// correctness-critical order (ConfigMaps before the pod that mounts them).\ntype podBuildResult struct {\n\t// Pod is the fully constructed pod spec, ready to be created.\n\tPod *apiv1.Pod\n\t// ExtraObjects are auxiliary objects that must be created before the pod.\n\t// Currently this is the env/args offload ConfigMap (mounted by the pod), so\n\t// it MUST be created first and AlreadyExists is tolerated.\n\tExtraObjects []*apiv1.ConfigMap","sourceCodeStart":300,"sourceCodeEnd":336,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/workflow/controller/workflowpod.go#L300-L336","documentation":"Before building a pod, the controller substitutes global and local parameters into the template's podSpecPatch via common.ProcessArgs. If that substitution fails (bad variable reference, malformed template, missing parameter), the error is wrapped with this message so the user knows the patch stage — not the spec itself — was the problem.","triggerScenarios":"A podSpecPatch containing {{...}} variables that are undefined in the scope (neither global params nor the local parameters passed), or ProcessArgs failing on an invalid argument spec.","commonSituations":"PodSpecPatch referencing parameters not defined in the template or workflow; patch written for a different template context; typos in variable names like {{workflow.namee}}.","solutions":["Fix the variable names in podSpecPatch to reference defined parameters","Ensure referenced parameters exist (or add them) as workflow/template parameters","Test the patch expression inline in a small workflow before deploying"],"exampleFix":"// before\npodSpecPatch: '{\"containers\":[{\"name\":\"main\",\"image\":\"{{workflow.parameters.image}}\"}]}' // image param not defined\n// after\n# add to workflow spec:\narguments:\n  parameters:\n    - name: image\n      value: myimage:latest","handlingStrategy":"validation","validationCode":"// check all {{vars}} in podSpecPatch exist in params\ndefined := map[string]bool{ \"workflow.name\": true, /* globals + template params */ }\nfor _, v := range regexp.MustCompile(`\\{\\{([^}]+)\\}\\}`).FindAllStringSubmatch(patch, -1) {\n  if !defined[v[1]] { return fmt.Errorf(\"undefined var %s in podSpecPatch\", v[1]) }\n}","typeGuard":null,"tryCatchPattern":"processedTmpl, err := common.ProcessArgs(ctx, tmpl, args, globals, locals, false, ns, indexer)\nif err != nil {\n  return nil, fmt.Errorf(\"podSpecPatch substitution failed: %w\", err)\n}","preventionTips":["Reference only defined global/workflow/template parameters in podSpecPatch","Test podSpecPatch with a minimal workflow first","Avoid hand-editing variable names in YAML without linting"],"tags":["kubernetes","podspec-patch","parameter-substitution","argo-workflows"],"backgroundTag":"parameter-substitution-failed","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"}