argoproj/argo-workflows · error
containers must have at least one container
Error message
containers must have at least one container
What it means
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.
Source
Thrown at pkg/apis/workflow/v1alpha1/container_set_template_types.go:92
if in == nil {
return nil
}
return in.Containers
}
func (in *ContainerSetTemplate) HasSequencedContainers() bool {
for _, n := range in.GetGraph() {
if len(n.Dependencies) > 0 {
return true
}
}
return false
}
// Validate checks if the ContainerSetTemplate is valid
func (in *ContainerSetTemplate) Validate() error {
if len(in.Containers) == 0 {
return fmt.Errorf("containers must have at least one container")
}
names := make([]string, 0)
for _, ctr := range in.Containers {
names = append(names, ctr.Name)
}
err := validateWorkflowFieldNames(names, false)
if err != nil {
return fmt.Errorf("containers%s", err.Error())
}
// Ensure there are no collisions with volume mountPaths and artifact load paths
mountPaths := make(map[string]string)
for i, volMount := range in.VolumeMounts {
if prev, ok := mountPaths[volMount.MountPath]; ok {
return fmt.Errorf("volumeMounts[%d].mountPath '%s' already mounted in %s", i, volMount.MountPath, prev)
}
mountPaths[volMount.MountPath] = fmt.Sprintf("volumeMounts.%s", volMount.Name)View on GitHub (pinned to 35bff19146)
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.
Example fix
// before
containerSet:
containers: []
// after
containerSet:
containers:
- name: main
image: alpine:3.18 Defensive patterns
Strategy: validation
Validate before calling
if cs.ContainerSet != nil && len(cs.ContainerSet.Containers) == 0 {
return fmt.Errorf("containerSet requires at least one container")
} Try / catch
if err := cs.Validate(); err != nil {
if strings.Contains(err.Error(), "must have at least one container") {
// fall back to a regular container template or reject the manifest
}
return err
} Prevention
- Check rendered manifests for empty lists after templating.
- Use plain container templates when only one container is needed.
- Validate with `argo lint` before submission.
When it happens
Trigger: Submitting or validating a workflow whose containerSet.containers array is empty or omitted, e.g. containers: [] in the template spec.
Common situations: 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.
Related errors
- duration has to be positive, current duration: %v
- containers%s
- volumeMounts[%d].mountPath '%s' already mounted in %s
- duplicate synchronization item found
- CodeBadRequest
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/f829dbfd6e4a0551.
Report an issue: GitHub.