{"record":{"id":"f829dbfd6e4a0551","repo":"argoproj/argo-workflows","slug":"containers-must-have-at-least-one-container","errorCode":null,"errorMessage":"containers must have at least one container","messagePattern":"containers must have at least one container","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/apis/workflow/v1alpha1/container_set_template_types.go","lineNumber":92,"sourceCode":"\tif in == nil {\n\t\treturn nil\n\t}\n\treturn in.Containers\n}\n\nfunc (in *ContainerSetTemplate) HasSequencedContainers() bool {\n\tfor _, n := range in.GetGraph() {\n\t\tif len(n.Dependencies) > 0 {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// Validate checks if the ContainerSetTemplate is valid\nfunc (in *ContainerSetTemplate) Validate() error {\n\tif len(in.Containers) == 0 {\n\t\treturn fmt.Errorf(\"containers must have at least one container\")\n\t}\n\n\tnames := make([]string, 0)\n\tfor _, ctr := range in.Containers {\n\t\tnames = append(names, ctr.Name)\n\t}\n\terr := validateWorkflowFieldNames(names, false)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"containers%s\", err.Error())\n\t}\n\n\t// Ensure there are no collisions with volume mountPaths and artifact load paths\n\tmountPaths := make(map[string]string)\n\tfor i, volMount := range in.VolumeMounts {\n\t\tif prev, ok := mountPaths[volMount.MountPath]; ok {\n\t\t\treturn fmt.Errorf(\"volumeMounts[%d].mountPath '%s' already mounted in %s\", i, volMount.MountPath, prev)\n\t\t}\n\t\tmountPaths[volMount.MountPath] = fmt.Sprintf(\"volumeMounts.%s\", volMount.Name)","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/pkg/apis/workflow/v1alpha1/container_set_template_types.go#L74-L110","documentation":"ContainerSetTemplate.Validate enforces that a container set declares at least one container. This structural validation guard fires during workflow/template validation (via validateContainerSetTemplate and validateLeaf) when a template uses a containerSet with an empty containers list, which cannot produce a runnable pod.","triggerScenarios":"Submitting or validating a workflow whose containerSet.containers array is empty or omitted, e.g. containers: [] in the template spec.","commonSituations":"Templating engine rendered the containers list away (empty loop/conditional); user wrote a containerSet but left the containers block blank; YAML key misspelled so containers is nil.","solutions":["Add at least one container entry with a valid name and image under containerSet.containers.","Fix the templating/variable that caused the containers list to render empty.","If you only need a single container, use a plain container/script template instead of a containerSet."],"exampleFix":"// before\ncontainerSet:\n  containers: []\n// after\ncontainerSet:\n  containers:\n    - name: main\n      image: alpine:3.18","handlingStrategy":"validation","validationCode":"if cs.ContainerSet != nil && len(cs.ContainerSet.Containers) == 0 {\n    return fmt.Errorf(\"containerSet requires at least one container\")\n}","typeGuard":null,"tryCatchPattern":"if err := cs.Validate(); err != nil {\n    if strings.Contains(err.Error(), \"must have at least one container\") {\n        // fall back to a regular container template or reject the manifest\n    }\n    return err\n}","preventionTips":["Check rendered manifests for empty lists after templating.","Use plain container templates when only one container is needed.","Validate with `argo lint` before submission."],"tags":["go","validation","container-set","argo-workflows"],"backgroundTag":"empty-container-set","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"}