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, errView on GitHub (pinned to 35bff19146)
Solutions
- Inspect the artifact spec producing the failure (kubectl get wf <name> -o yaml) and ensure `subPath` is a plain string.
- Rebuild/resubmit the workflow with a corrected artifact definition.
- 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
- Ensure subPath is always a plain string when building artifacts via SDKs
- Validate artifact specs with argo lint before submission
- Avoid plugins/custom sources injecting non-string subPath values
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.