argoproj/argo-workflows · error

template artifact location not set

Error message

template artifact location not set

What it means

ArtifactLocation.Relocate copies the template-level artifact location (e.g. the artifact repository defaults with a key prefix) onto an artifact that has no location of its own. If the source template location `l` is nil — meaning the containing template/workflow has no artifact location configured — there is nothing to relocate and this error is returned.

Source

Thrown at pkg/apis/workflow/v1alpha1/workflow_types.go:1511

	return v.SetKey(key)
}

func (a *ArtifactLocation) AppendToKey(x string) error {
	key, err := a.GetKey()
	if err != nil {
		return err
	}
	return a.SetKey(path.Join(key, x))
}

// Relocate copies all location info from the parameter, except the key.
// But only if it does not have a location already.
func (a *ArtifactLocation) Relocate(l *ArtifactLocation) error {
	if a.HasLocation() {
		return nil
	}
	if l == nil {
		return fmt.Errorf("template artifact location not set")
	}
	key, err := a.GetKey()
	if err != nil {
		return err
	}
	*a = *l.DeepCopy()
	return a.SetKey(key)
}

// HasLocation whether or not an artifact has a *full* location defined
// An artifact that has a location implicitly has a key (i.e. HasKey() == true).
func (a *ArtifactLocation) HasLocation() bool {
	v, err := a.Get()
	return err == nil && v.HasLocation()
}

func (a *ArtifactLocation) IsArchiveLogs() bool {
	return a != nil && a.ArchiveLogs != nil && *a.ArchiveLogs

View on GitHub (pinned to 35bff19146)

Solutions

  1. Configure the template/workflow artifact location (artifactRepository in controller config or template's artifactLocation)
  2. Ensure the template used has a non-nil artifact location before artifacts rely on Relocate
  3. Check HasLocation() on the artifact first; if it already has a location, Relocate is a no-op and the nil template location does not matter

Example fix

// before
tmpl := &WorkflowTemplate{} // artifact location never set
err := art.Locate.Relocate(tmpl.GetArtifactLocation()) // nil -> error
// after
tmpl.Spec.Templates[0].ArtifactLocation = &ArtifactLocation{S3: &S3Artifact{Key: "prefix"}}
err := art.Locate.Relocate(tmpl.GetArtifactLocation())
Defensive patterns

Strategy: type-guard

Validate before calling

if l == nil {
    return errors.New("template has no artifact location; configure artifactRepository first")
}

Type guard

func relocateReady(a, l *ArtifactLocation) bool {
    return a == nil || !a.HasLocation() && l != nil
}

Try / catch

if err := art.Locate.Relocate(tmplLoc); err != nil {
    if strings.Contains(err.Error(), "template artifact location not set") {
        return errors.New("configure artifactRepository on the template/controller before running")
    }
    return err
}

Prevention

When it happens

Trigger: Calling Relocate on an artifact without its own location, passing a nil *ArtifactLocation for the template location; happens in controller/executor code that resolves output artifact paths against the template's artifact location.

Common situations: Workflow template created without an artifactRepository/location while an artifact relies on relocation; controller hydrating artifacts from a template whose location was never set.

Related errors


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