{"record":{"id":"929d8bb6e460a4dc","repo":"argoproj/argo-workflows","slug":"duplicate-clusterworkflowtemplate-found-q","errorCode":null,"errorMessage":"duplicate ClusterWorkflowTemplate found: %q","messagePattern":"duplicate ClusterWorkflowTemplate found: %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/apiclient/offline-client.go","lineNumber":68,"sourceCode":"\tfor _, basePath := range paths {\n\t\terr := file.WalkManifests(ctx, basePath, func(path string, bytes []byte) error {\n\t\t\tfor _, pr := range common.ParseObjects(ctx, bytes, false) {\n\t\t\t\tobj, err := pr.Object, pr.Err\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn fmt.Errorf(\"failed to parse YAML from file %s: %w\", path, err)\n\t\t\t\t}\n\n\t\t\t\tif obj == nil {\n\t\t\t\t\tcontinue // could not parse to kubernetes object\n\t\t\t\t}\n\n\t\t\t\tobjName := obj.GetName()\n\t\t\t\tnamespace := obj.GetNamespace()\n\n\t\t\t\tswitch v := obj.(type) {\n\t\t\t\tcase *wfv1.ClusterWorkflowTemplate:\n\t\t\t\t\tif _, ok := clusterWorkflowTemplateGetter.clusterWorkflowTemplates[objName]; ok {\n\t\t\t\t\t\treturn fmt.Errorf(\"duplicate ClusterWorkflowTemplate found: %q\", objName)\n\t\t\t\t\t}\n\t\t\t\t\tclusterWorkflowTemplateGetter.clusterWorkflowTemplates[objName] = v\n\n\t\t\t\tcase *wfv1.WorkflowTemplate:\n\t\t\t\t\tgetter, ok := workflowTemplateGetters[namespace]\n\t\t\t\t\tif !ok {\n\t\t\t\t\t\tgetter = &offlineWorkflowTemplateNamespacedGetter{\n\t\t\t\t\t\t\tnamespace:         namespace,\n\t\t\t\t\t\t\tworkflowTemplates: map[string]*wfv1.WorkflowTemplate{},\n\t\t\t\t\t\t}\n\t\t\t\t\t\tworkflowTemplateGetters[namespace] = getter\n\t\t\t\t\t}\n\n\t\t\t\t\tif _, ok := getter.(*offlineWorkflowTemplateNamespacedGetter).workflowTemplates[objName]; ok {\n\t\t\t\t\t\treturn fmt.Errorf(\"duplicate WorkflowTemplate found: %q\", objName)\n\t\t\t\t\t}\n\t\t\t\t\tgetter.(*offlineWorkflowTemplateNamespacedGetter).workflowTemplates[objName] = v\n\t\t\t\t}","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/pkg/apiclient/offline-client.go#L50-L86","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\napiVersion: argoproj.io/v1alpha1\nkind: ClusterWorkflowTemplate\nmetadata:\n  name: my-template\n// (same name in second file)\n// after\nmetadata:\n  name: my-template-v2","handlingStrategy":"validation","validationCode":"func checkDupClusterTemplates(dir string) error {\n    seen := map[string]bool{}\n    return filepath.Walk(dir, func(p string, _ fs.FileInfo, err error) error {\n        // parse docs, if kind==ClusterWorkflowTemplate:\n        // if seen[name] { return fmt.Errorf(\"dup %s\", name) }; seen[name]=true\n        _ = seen\n        return err\n    })\n}","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"duplicate ClusterWorkflowTemplate found\") {\n    // extract quoted name from err, grep manifests for that name\n    return fmt.Errorf(\"remove or rename one of the duplicates: %w\", err)\n}","preventionTips":["Keep one canonical file per ClusterWorkflowTemplate.","Exclude stale/backup manifests from linted directories.","After kustomize/Helm rendering, dedupe output before linting."],"tags":["go","offline-mode","duplicate-resources","lint"],"backgroundTag":"duplicate-resource-definition","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"}