argoproj/argo-workflows · error

can't find template with name %q

Error message

can't find template with name %q

What it means

createArtifactGCPod iterates templatesToArtList and resolves each template from the templatesByName map built earlier in processArtifactGCStrategy. If a key is missing, the map and artifact list are out of sync. Thrown at workflow/controller/artifact_gc.go:394; like error 551 it guards an internal invariant and is normally unreachable with upstream code.

Source

Thrown at workflow/controller/artifact_gc.go:394

// create the Pod which will do the deletions
func (woc *wfOperationCtx) createArtifactGCPod(ctx context.Context, strategy wfv1.ArtifactGCStrategy, tasks []*wfv1.WorkflowArtifactGCTask,
	info podInfo, podName string, templatesToArtList templatesToArtifacts, templatesByName map[string]*wfv1.Template) (*corev1.Pod, error) {
	woc.log.WithFields(logging.Fields{"strategy": strategy, "podName": podName}).Info(ctx, "creating pod to delete artifacts")

	// Pod is owned by WorkflowArtifactGCTasks, so it will die automatically when all of them have died
	ownerReferences := make([]metav1.OwnerReference, len(tasks))
	for i, task := range tasks {
		// make sure pod gets deleted with the WorkflowArtifactGCTasks
		ownerReferences[i] = *metav1.NewControllerRef(task, wfv1.SchemeGroupVersion.WithKind(workflow.WorkflowArtifactGCTaskKind))
	}

	artifactLocations := make([]*wfv1.ArtifactLocation, 0)

	for templateName, artifacts := range templatesToArtList {
		template, found := templatesByName[templateName]
		if !found {
			return nil, fmt.Errorf("can't find template with name %q", templateName)
		}

		if template.ArchiveLocation.HasLocation() {
			artifactLocations = append(artifactLocations, template.ArchiveLocation)
		} else {
			artifactLocations = append(artifactLocations, woc.artifactRepository.ToArtifactLocation())
		}
		for i := range artifacts {
			artifactLocations = append(artifactLocations, &artifacts[i].ArtifactLocation)
		}
	}

	volumes, volumeMounts := createSecretVolumesAndMountsFromArtifactLocations(artifactLocations)

	pluginNames := make(map[wfv1.ArtifactPluginName]bool, 0)
	for _, artifactLocation := range artifactLocations {
		if artifactLocation != nil && artifactLocation.Plugin != nil && artifactLocation.Plugin.Name != "" {
			pluginNames[artifactLocation.Plugin.Name] = true

View on GitHub (pinned to 35bff19146)

Solutions

  1. Run unmodified upstream workflow-controller; rebuild the image if artifact_gc.go was customized.
  2. Enable debug logging (logging.globalLevel=debug) and capture the 'list of artifacts pertaining to template' lines to identify the inconsistent template name.
  3. Report the issue upstream with controller version and workflow spec.
  4. As a workaround, use spec.artifactGC.forceFinalizerRemoval: true and remove artifacts manually.
Defensive patterns

Strategy: try-catch

Try / catch

if strings.Contains(err.Error(), "can't find template with name") { /* internal inconsistency: report upstream, use forceFinalizerRemoval workaround */ }

Prevention

When it happens

Trigger: templatesToArtList contains a templateName key absent from templatesByName. Both are populated from the same resolution pass, so this fires only from code modifications, map mutation between passes, or a nil template being cached under its name in a fork.

Common situations: Patched/forked controller code altering the templatesByName population; upstream bug reports concerning map consistency during artifact GC strategy processing.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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