argoproj/argo-workflows · error
cannot fetch workflow spec without workflowTemplateRef
Error message
cannot fetch workflow spec without workflowTemplateRef
What it means
The controller's fetchWorkflowSpec only supports workflows whose spec uses workflowTemplateRef to source their spec from a WorkflowTemplate. If a workflow has an inline spec (no workflowTemplateRef), the controller cannot retrieve a spec holder and returns this error, aborting reconciliation of that workflow.
Source
Thrown at workflow/controller/operator.go:4451
return false, nil
}
parentTemplate, templateStored, err := woc.GetTemplateByBoundaryID(ctx, boundaryID)
if err != nil || parentTemplate == nil {
return false, err
}
// A new template was stored during resolution, persist it
if templateStored {
woc.updated = true
}
name := getStepOrDAGTaskName(nodeName)
return woc.hasOutputResultRef(ctx, name, parentTemplate), nil
}
func (woc *wfOperationCtx) fetchWorkflowSpec(ctx context.Context) (wfv1.WorkflowSpecHolder, error) {
if woc.wf.Spec.WorkflowTemplateRef == nil { //nolint:forbidigo // not-woc-misuse
return nil, fmt.Errorf("cannot fetch workflow spec without workflowTemplateRef")
}
var specHolder wfv1.WorkflowSpecHolder
var err error
// Logic for workflow refers Workflow template
if woc.wf.Spec.WorkflowTemplateRef.ClusterScope { //nolint:forbidigo // not-woc-misuse
if woc.controller.cwftmplInformer == nil {
woc.log.WithError(err).Error(ctx, "clusterWorkflowTemplate RBAC is missing")
return nil, fmt.Errorf("cannot get resource clusterWorkflowTemplate at cluster scope")
}
woc.controller.metrics.CountWorkflowTemplate(ctx, metrics.WorkflowNew, woc.wf.Spec.WorkflowTemplateRef.Name, woc.wf.Namespace, true) //nolint:forbidigo // not-woc-misuse
specHolder, err = woc.controller.cwftmplInformer.Lister().Get(woc.wf.Spec.WorkflowTemplateRef.Name) //nolint:forbidigo // not-woc-misuse
} else {
woc.controller.metrics.CountWorkflowTemplate(ctx, metrics.WorkflowNew, woc.wf.Spec.WorkflowTemplateRef.Name, woc.wf.Namespace, false) //nolint:forbidigo // not-woc-misuse
specHolder, err = woc.controller.wftmplInformer.Lister().WorkflowTemplates(woc.wf.Namespace).Get(woc.wf.Spec.WorkflowTemplateRef.Name) //nolint:forbidigo // not-woc-misuse
}
if err != nil {
return nil, errView on GitHub (pinned to 35bff19146)
Solutions
- Convert the workflow to reference a WorkflowTemplate by setting spec.workflowTemplateRef.name
- Check the submitted YAML: workflowTemplateRef must be a direct child of spec, not nested elsewhere
- If inline specs are intended, ensure the controller code path taken does not require fetching the template spec (not in reference/secure mode)
Example fix
// before
spec:
entrypoint: main
templates:
- name: main
container:
image: alpine
// after
spec:
entrypoint: main
workflowTemplateRef:
name: my-template Defensive patterns
Strategy: validation
Validate before calling
if wf.Spec.WorkflowTemplateRef == nil {
return fmt.Errorf("workflow %s must set spec.workflowTemplateRef", wf.Name)
} Type guard
func hasTemplateRef(wf *wfv1.Workflow) bool { return wf != nil && wf.Spec.WorkflowTemplateRef != nil } Prevention
- Always submit template-based workflows when using template referencing features
- Run argo lint before submitting
- Keep workflowTemplateRef at the correct YAML nesting under spec
When it happens
Trigger: Reconciling a Workflow whose Spec.WorkflowTemplateRef is nil while executing the code path that requires fetching the referenced template spec (e.g. template referencing / stored-spec resolution in operator.go).
Common situations: Users submit workflows with fully inline specs (the traditional style) while the controller or code path assumes template-based workflows; older workflows migrated before workflowTemplateRef existed; YAML that accidentally places workflowTemplateRef at the wrong nesting level so it is not parsed.
Related errors
- critical error; unable to find %s
- no Node found by the name of %s; wf.Status.Nodes=%+v
- no Retry Node found by the name of %s; wf.Status.Nodes=%+v
- workflows must use workflowTemplateRef to be executed when t
- failed to read container args file %s: %w
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/fbe109bcd7975405.
Report an issue: GitHub.