argoproj/argo-workflows · error

CodeBadRequest

CodeBadRequest

Error message

failed to marshal artifact subpath for templating

What it means

When resolving an artifact with a `subPath` expression, the controller marshals the raw SubPath string to JSON so it can be template-rendered. A json.Marshal failure here is effectively impossible for plain strings, but if it happens the controller returns this CodeBadRequest error instead of proceeding with a corrupted value.

Source

Thrown at workflow/controller/scope.go:236

		return nil, err
	}
	valArt, ok := val.(wfv1.Artifact)
	if !ok {
		// If the workflow refers itself input artifacts in fromExpression, the val type is "*wfv1.Artifact"
		ptArt, ok := val.(*wfv1.Artifact)
		if !ok {
			return nil, errors.Errorf(errors.CodeBadRequest, "Variable {{%v}} is not an artifact", art)
		}
		valArt = *ptArt
	}

	if art.SubPath != "" {
		// Copy resolved artifact pointer before adding subpath
		copyArt := valArt.DeepCopy()

		subPathAsJSON, err := json.Marshal(art.SubPath)
		if err != nil {
			return copyArt, errors.New(errors.CodeBadRequest, "failed to marshal artifact subpath for templating")
		}

		resolvedSubPathAsJSON, err := template.Replace(ctx, string(subPathAsJSON), s.getParametersAny(nil), true)
		if err != nil {
			return nil, err
		}

		var resolvedSubPath string
		err = json.Unmarshal([]byte(resolvedSubPathAsJSON), &resolvedSubPath)
		if err != nil {
			return copyArt, errors.New(errors.CodeBadRequest, "failed to unmarshal artifact subpath for templating")
		}

		err = copyArt.AppendToKey(resolvedSubPath)
		if err != nil && copyArt.Optional { // Ignore error when artifact optional
			return copyArt, nil
		}
		return copyArt, err

View on GitHub (pinned to 35bff19146)

Solutions

  1. Inspect the artifact spec producing the failure (kubectl get wf <name> -o yaml) and ensure `subPath` is a plain string.
  2. Rebuild/resubmit the workflow with a corrected artifact definition.
  3. If building artifacts via SDK, ensure subPath is passed as a string, not another JSON type.

Example fix

// before (SDK-built artifact)
art.SubPath = 42
// after
art.SubPath = "data/output.txt"
Defensive patterns

Strategy: validation

Validate before calling

if art.SubPath != "" {
    if _, err := json.Marshal(art.SubPath); err != nil {
        return fmt.Errorf("artifact subPath %q is not a valid string value", art.SubPath)
    }
}

Try / catch

resolved, err := scope.ResolveArtifact(ctx, art)
if err != nil && strings.Contains(err.Error(), "failed to marshal artifact subpath") {
    // inspect artifact spec in the Workflow YAML and fix subPath
}

Prevention

When it happens

Trigger: Calling resolveArtifact on an artifact whose SubPath is set and json.Marshal(art.SubPath) returns an error (e.g. unexpected/invalid value passed through the API or a custom artifact source).

Common situations: Practically rare; seen when artifact specs are built programmatically or via SDKs with unusual values, or when a controller/plugin feeds malformed artifact data into scope resolution.

Related errors


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