argoproj/argo-workflows · error
unable to parse argo variable: %w
Error message
unable to parse argo variable: %w
What it means
expandStep marshals the step template to JSON and runs template.NewTemplate to validate/parse its argo variables. If the template syntax is invalid (unbalanced braces, malformed {{...}} expressions), expansion of withItems/withParam fails with this wrapped parse error.
Source
Thrown at workflow/controller/steps.go:646
}
default:
// this should have been prevented in expandStepGroup()
return nil, argoerrors.InternalError("expandStep() was called with withItems and withParam empty")
}
// these fields can be very large (>100m) and marshalling 10k x 100m = 6GB of memory used and
// very poor performance, so we just nil them out
step.WithItems = nil
step.WithParam = ""
step.WithSequence = nil
stepBytes, err := json.Marshal(step)
if err != nil {
return nil, argoerrors.InternalWrapError(err)
}
t, err := template.NewTemplate(string(stepBytes))
if err != nil {
return nil, fmt.Errorf("unable to parse argo variable: %w", err)
}
for i, item := range items {
var newStep wfv1.WorkflowStep
newStepName, err := processItem(ctx, t, step.Name, i, item, &newStep, step.When, scope.getParametersAny(woc.globalParams()))
if err != nil {
return nil, err
}
newStep.Name = newStepName
newStep.Template = step.Template
expandedStep = append(expandedStep, newStep)
}
return expandedStep, nil
}
func (woc *wfOperationCtx) prepareDefaultMetricScope() (map[string]any, map[string]func() float64) {
localScope := template.ToAnyMap(woc.globalParams())
localScope[varkeys.MetricDuration.Template()] = "0"View on GitHub (pinned to 35bff19146)
Solutions
- Fix the malformed {{...}} expression in the step template
- Validate the workflow with argo lint before submitting
- Escape literal braces or move complex expressions into scripts
Example fix
// before
- name: fanout
template: echo
withItems: [1, 2]
arguments:
parameters:
- name: msg
value: 'hello {{item}} }' # unbalanced brace
// after
arguments:
parameters:
- name: msg
value: 'hello {{item}}' Defensive patterns
Strategy: validation
Validate before calling
// check for balanced braces in templated strings before submit
func balancedBraces(s string) bool { c := 0; for _, r := range s { if r=='{' {c++}; if r=='}' {c--}; if c>1||c<0 {return false} }; return c==0 } Try / catch
if strings.Contains(err.Error(), "unable to parse argo variable") {
// fix malformed {{...}} in the step template and resubmit
} Prevention
- Run argo lint in CI
- Avoid stray braces in parameter values
- Prefer simple expressions; escape literals
When it happens
Trigger: expandStep on a step using withItems/withMap/withParam where the step's templated strings contain malformed argo variable syntax that template.NewTemplate cannot parse.
Common situations: Unbalanced {{ }} braces, stray single braces, invalid expression syntax inside item loops; YAML anchors producing odd strings; typos like {{item}} misspellings.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- step group deemed errored due to child %s error: %w
- was unable to obtain childNode for %s
- unable to resolve references: %w
- failed to resolve references: %w
- failed to read container args file %s: %w
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/a72850a1b6d8bfd3.
Report an issue: GitHub.