{"record":{"id":"cf021ce5412a336e","repo":"argoproj/argo-workflows","slug":"badrequest","errorCode":"BadRequest","errorMessage":"templates.%s.script.image may not be empty","messagePattern":"templates\\.(.+?)\\.script\\.image may not be empty","errorType":"validation","errorClass":"ArgoError","httpStatus":null,"severity":"error","filePath":"workflow/validate/validate.go","lineNumber":974,"sourceCode":"\t\t\t\tif err != nil {\n\t\t\t\t\treturn errors.Errorf(errors.CodeBadRequest, \"templates.%s.resource.manifest must be a valid yaml\", tmpl.Name)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tif tmpl.Script != nil {\n\t\tif tmpl.Script.Image == \"\" {\n\t\t\tswitch baseTemplate := tmplCtx.GetCurrentTemplateBase().(type) {\n\t\t\tcase *wfv1.Workflow:\n\t\t\t\tif baseTemplate.Spec.TemplateDefaults == nil || baseTemplate.Spec.TemplateDefaults.Script == nil || baseTemplate.Spec.TemplateDefaults.Script.Image == \"\" {\n\t\t\t\t\treturn errors.Errorf(errors.CodeBadRequest, \"templates.%s.script.image may not be empty\", tmpl.Name)\n\t\t\t\t}\n\t\t\tcase *wfv1.WorkflowTemplate:\n\t\t\t\tif baseTemplate.Spec.TemplateDefaults == nil || baseTemplate.Spec.TemplateDefaults.Script == nil || baseTemplate.Spec.TemplateDefaults.Script.Image == \"\" {\n\t\t\t\t\treturn errors.Errorf(errors.CodeBadRequest, \"templates.%s.script.image may not be empty\", tmpl.Name)\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\treturn errors.Errorf(errors.CodeBadRequest, \"templates.%s.script.image may not be empty\", tmpl.Name)\n\t\t\t}\n\t\t}\n\t}\n\t// we don't validate tmpl.Plugin, because this is done by Plugin.UnmarshallJSON\n\tif tmpl.ActiveDeadlineSeconds != nil {\n\t\tif !intstr.IsValidIntOrArgoVariable(tmpl.ActiveDeadlineSeconds) && !placeholderGenerator.IsPlaceholder(tmpl.ActiveDeadlineSeconds.StrVal) {\n\t\t\treturn errors.Errorf(errors.CodeBadRequest, \"templates.%s.activeDeadlineSeconds must be a positive integer > 0 or an argo variable\", tmpl.Name)\n\t\t}\n\t\tif i, err := intstr.Int(tmpl.ActiveDeadlineSeconds); err == nil && i != nil && *i < 0 {\n\t\t\treturn errors.Errorf(errors.CodeBadRequest, \"templates.%s.activeDeadlineSeconds must be a positive integer > 0 or an argo variable\", tmpl.Name)\n\t\t}\n\t}\n\tif tmpl.Parallelism != nil {\n\t\treturn errors.Errorf(errors.CodeBadRequest, \"templates.%s.parallelism is only valid for steps and dag templates\", tmpl.Name)\n\t}\n\treturn nil\n}\n","sourceCodeStart":956,"sourceCodeEnd":992,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/workflow/validate/validate.go#L956-L992","documentation":"The `default` branch of the script-image check: if the current template base is neither a Workflow nor a WorkflowTemplate (e.g. a ClusterWorkflowTemplate or unknown base kind), the validator cannot consult templateDefaults, so an empty `script.image` is unconditionally rejected. Ensures every script template ends up with a resolvable container image.","triggerScenarios":"A script template without `image` validated against a base template kind other than Workflow/WorkflowTemplate — typically when templates come from ClusterWorkflowTemplates or the template context returns an unexpected type.","commonSituations":"Referencing a ClusterWorkflowTemplate that itself lacks a script image and has no defaults honored by this check; custom/older CRD kinds passing through validation.","solutions":["Always set `script.image` explicitly on script templates referenced via ClusterWorkflowTemplate.","Move the script template into a WorkflowTemplate/Workflow where templateDefaults can be consulted, and set defaults there.","Check `tmplCtx.GetCurrentTemplateBase()` resolution if you believe the kind is wrong."],"exampleFix":"// before\nscript:\n  source: echo hi\n// after\nscript:\n  image: alpine:3.19\n  source: echo hi","handlingStrategy":"validation","validationCode":"if (tmpl.script && !tmpl.script.image) {\n  throw new Error('script.image must be explicit when base kind is not Workflow/WorkflowTemplate (e.g. ClusterWorkflowTemplate)');\n}","typeGuard":"function scriptImageExplicit(t) {\n  return !t.script || Boolean(t.script.image);\n}","tryCatchPattern":null,"preventionTips":["Never rely on defaults for ClusterWorkflowTemplate-referenced script templates","Make script.image a required field in your workflow authoring tooling","Pin images explicitly for auditability"],"tags":["argo-workflows","validation","script-template","clusterworkflowtemplate"],"backgroundTag":"missing-required-argument","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"}