argoproj/argo-workflows · error

duplicate WorkflowTemplate found

Error message

duplicate WorkflowTemplate found: %q

What it means

Same duplicate-detection as ClusterWorkflowTemplates but namespaced: offline client stores WorkflowTemplates per namespace by name. Two WorkflowTemplates sharing a name within the same namespace in the linted manifests make the store ambiguous and abort with this error.

Solutions

  1. Rename one of the conflicting WorkflowTemplates or change one's namespace.
  2. Remove the redundant file/document from the linted set.
  3. Search the manifests for `name: <offending>` under kind: WorkflowTemplate to locate both.

Example fix

// before
kind: WorkflowTemplate
metadata:
  name: dup
  namespace: default
// after
kind: WorkflowTemplate
metadata:
  name: dup-alt
  namespace: default
Defensive patterns

Strategy: validation

Validate before calling

seen := map[string]bool{}
// for each parsed WorkflowTemplate doc:
key := ns + "/" + name
if seen[key] { return fmt.Errorf("duplicate WorkflowTemplate %s", key) }
seen[key] = true

Try / catch

if err != nil && strings.Contains(err.Error(), "duplicate WorkflowTemplate found") {
    // name is quoted inside err; locate both (namespace,name) occurrences and fix
    return err
}

Prevention

When it happens

Trigger: Linting paths containing two WorkflowTemplates with identical metadata.name AND identical metadata.namespace (duplicates in different namespaces are allowed).

Common situations: Duplicated manifests in a directory passed to `argo lint`; accidentally rendering the same template twice with different values files but the same name; forgetting to change the name when creating a variant.

Related errors


AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03). Data as JSON: /api/errors/519ad17c0210fd0e. Report an issue: GitHub.

Appendix: source

Thrown at pkg/apiclient/offline-client.go:83

				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
				}
			}
			return nil
		})

		if err != nil {
			return nil, nil, err
		}
	}

	return ctx, &offlineClient{
		clusterWorkflowTemplateGetter:       clusterWorkflowTemplateGetter,
		namespacedWorkflowTemplateGetterMap: workflowTemplateGetters,
	}, nil
}

View on GitHub (pinned to 35bff19146)