argoproj/argo-workflows · error

404

404

Error message

template %s not found

What it means

TemplateContext.GetTemplateByName resolves a template by name from the template base (workflow, WorkflowTemplate, or ClusterWorkflowTemplate already loaded into context). If no template with that name exists in the base, it returns a 404 CodeNotFound error so callers (validation, GetTemplate) fail with a clear not-found message.

Source

Thrown at workflow/templateresolution/context.go:107

// NewContextFromClientSet returns new Context.
func NewContextFromClientSet(wftmplClientset typed.WorkflowTemplateInterface, clusterWftmplClient typed.ClusterWorkflowTemplateInterface, tmplBase wfv1.TemplateHolder, workflow *wfv1.Workflow, log logging.Logger) *TemplateContext {
	return &TemplateContext{
		wftmplGetter:  WrapWorkflowTemplateInterface(wftmplClientset),
		cwftmplGetter: WrapClusterWorkflowTemplateInterface(clusterWftmplClient),
		tmplBase:      tmplBase,
		workflow:      workflow,
		log:           log,
	}
}

// GetTemplateByName returns a template by name in the context.
func (tplCtx *TemplateContext) GetTemplateByName(ctx context.Context, name string) (*wfv1.Template, error) {
	tplCtx.log.WithField("name", name).Debug(ctx, "Getting the template by name")

	tmpl := tplCtx.tmplBase.GetTemplateByName(name)
	if tmpl == nil {
		return nil, errors.Errorf(errors.CodeNotFound, "template %s not found", name)
	}

	podMetadata := tplCtx.tmplBase.GetPodMetadata()
	tplCtx.addPodMetadata(podMetadata, tmpl)

	return tmpl.DeepCopy(), nil
}

func (tplCtx *TemplateContext) GetTemplateGetterFromRef(ctx context.Context, tmplRef *wfv1.TemplateRef) (wfv1.TemplateHolder, error) {
	if tmplRef.ClusterScope {
		return tplCtx.cwftmplGetter.Get(ctx, tmplRef.Name)
	}
	return tplCtx.wftmplGetter.Get(ctx, tmplRef.Name)
}

// GetTemplateFromRef returns a template found by a given template ref.
func (tplCtx *TemplateContext) GetTemplateFromRef(ctx context.Context, tmplRef *wfv1.TemplateRef) (*wfv1.Template, error) {
	tplCtx.log.Debug(ctx, "Getting the template from ref")

View on GitHub (pinned to 35bff19146)

Solutions

  1. Correct the template name in the step/task/templateRef
  2. Verify the referenced WorkflowTemplate actually contains the template
  3. Run `argo lint` before submitting to catch missing templates

Example fix

// before
- name: step-a
  template: build-image  # does not exist
// after
- name: step-a
  template: build  # matches templates[].name in the spec
Defensive patterns

Strategy: validation

Validate before calling

// pre-check that the template exists in the holder
names := set(tmplBase.Templates.map(t => t.Name))
for (const ref of allTemplateRefs(wf)) {
  if (!names.has(ref)) throw new Error(`template ${ref} not found`)
}

Try / catch

tmpl, err := tplCtx.GetTemplateByName(ctx, name)
if err != nil {
  var nf *errors.ArgoError
  if errors.As(err, &nf) && nf.Code() == 404 {
    return fmt.Errorf("template %q missing from spec; run argo lint", name)
  }
  return err
}

Prevention

When it happens

Trigger: Calling GetTemplate/GetTemplateByName with a template name that doesn't exist in the referenced template holder; validateTemplateHolder on a spec whose templates list lacks the referenced name.

Common situations: Typos in template names; steps/tasks referencing templates removed during refactoring; templateRef pointing to a template that exists in a different WorkflowTemplate than the one named.

Related errors


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