argoproj/argo-workflows · error
duplicate ClusterWorkflowTemplate found: %q
Error message
duplicate ClusterWorkflowTemplate found: %q
What it means
The offline client indexes ClusterWorkflowTemplates by name in a map. If the walked manifests contain two ClusterWorkflowTemplates with the same metadata.name, the store cannot resolve unambiguously, so newOfflineClient fails with this duplicate error.
Source
Thrown at pkg/apiclient/offline-client.go:68
for _, basePath := range paths {
err := file.WalkManifests(ctx, basePath, func(path string, bytes []byte) error {
for _, pr := range common.ParseObjects(ctx, bytes, false) {
obj, err := pr.Object, pr.Err
if err != nil {
return fmt.Errorf("failed to parse YAML from file %s: %w", path, err)
}
if obj == nil {
continue // could not parse to kubernetes object
}
objName := obj.GetName()
namespace := obj.GetNamespace()
switch v := obj.(type) {
case *wfv1.ClusterWorkflowTemplate:
if _, ok := clusterWorkflowTemplateGetter.clusterWorkflowTemplates[objName]; ok {
return fmt.Errorf("duplicate ClusterWorkflowTemplate found: %q", objName)
}
clusterWorkflowTemplateGetter.clusterWorkflowTemplates[objName] = v
case *wfv1.WorkflowTemplate:
getter, ok := workflowTemplateGetters[namespace]
if !ok {
getter = &offlineWorkflowTemplateNamespacedGetter{
namespace: namespace,
workflowTemplates: map[string]*wfv1.WorkflowTemplate{},
}
workflowTemplateGetters[namespace] = getter
}
if _, ok := getter.(*offlineWorkflowTemplateNamespacedGetter).workflowTemplates[objName]; ok {
return fmt.Errorf("duplicate WorkflowTemplate found: %q", objName)
}
getter.(*offlineWorkflowTemplateNamespacedGetter).workflowTemplates[objName] = v
}View on GitHub (pinned to 35bff19146)
Solutions
- Rename one of the duplicate ClusterWorkflowTemplates (metadata.name must be unique).
- Delete or exclude the stale duplicate file from the linted paths.
- Grep the walked paths for the offending name to find both definitions.
Example fix
// before apiVersion: argoproj.io/v1alpha1 kind: ClusterWorkflowTemplate metadata: name: my-template // (same name in second file) // after metadata: name: my-template-v2
Defensive patterns
Strategy: validation
Validate before calling
func checkDupClusterTemplates(dir string) error {
seen := map[string]bool{}
return filepath.Walk(dir, func(p string, _ fs.FileInfo, err error) error {
// parse docs, if kind==ClusterWorkflowTemplate:
// if seen[name] { return fmt.Errorf("dup %s", name) }; seen[name]=true
_ = seen
return err
})
} Try / catch
if err != nil && strings.Contains(err.Error(), "duplicate ClusterWorkflowTemplate found") {
// extract quoted name from err, grep manifests for that name
return fmt.Errorf("remove or rename one of the duplicates: %w", err)
} Prevention
- Keep one canonical file per ClusterWorkflowTemplate.
- Exclude stale/backup manifests from linted directories.
- After kustomize/Helm rendering, dedupe output before linting.
When it happens
Trigger: Passing a set of paths to the offline client (e.g. `argo lint` with a directory) where two files, or two documents in one file, both define a ClusterWorkflowTemplate with the identical name.
Common situations: Copy-pasting a template into a second file and renaming only one; linting a directory that accumulates old versions of the same template; Helm/kustomize output that renders the same template twice.
Related errors
- duplicate WorkflowTemplate found: %q
- not supported when you are in offline mode
- couldn't find workflow template %q in namespace %q
- failed to parse YAML from file %s: %w
- couldn't find cluster workflow template %q
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/929d8bb6e460a4dc.
Report an issue: GitHub.