argoproj/argo-workflows · error
json: unknown field "%s"
Error message
json: unknown field "%s"
What it means
ParallelSteps (the anonymous list inside a template's `steps`) uses a custom UnmarshalJSON because WorkflowStep is serialized as a bare JSON list. Since the standard strict-decoding unknown-field enforcement does not apply to this custom unmarshaller, it manually checks each key against the fields of WorkflowStep and returns this error for any unrecognized key.
Source
Thrown at pkg/apis/workflow/v1alpha1/workflow_types.go:678
var candidate []map[string]any
err := json.Unmarshal(value, &candidate)
if err != nil {
return err
}
// Generate a list of all the available JSON fields of the WorkflowStep struct
availableFields := map[string]bool{}
reflectType := reflect.TypeFor[WorkflowStep]()
for field := range reflectType.Fields() {
cleanString := strings.ReplaceAll(field.Tag.Get("json"), ",omitempty", "")
availableFields[cleanString] = true
}
// Enforce that no unknown fields are present
for _, step := range candidate {
for key := range step {
if _, ok := availableFields[key]; !ok {
return fmt.Errorf(`json: unknown field "%s"`, key)
}
}
}
// Finally, attempt to fully unmarshal the struct
err = json.Unmarshal(value, &p.Steps)
if err != nil {
return err
}
return nil
}
func (p ParallelSteps) MarshalJSON() ([]byte, error) {
return json.Marshal(p.Steps)
}
func (p ParallelSteps) OpenAPISchemaType() []string {
return []string{"array"}View on GitHub (pinned to 35bff19146)
Solutions
- Fix the reported field name to a valid WorkflowStep field (name, template, templateRef, inline, arguments, when, onExit, continueOn, hooks, withItems, withParam, withSequence, etc.)
- Check the CRD schema version you are running against; remove fields not present in it
- Run `argo lint` locally to catch typos before applying
Example fix
// before - nam: build templete: build-template // after - name: build template: build-template
Defensive patterns
Strategy: validation
Validate before calling
var candidate []map[string]any
if err := json.Unmarshal(stepBytes, &candidate); err != nil {
return err
}
allowed := map[string]bool{"name":true,"template":true,"templateRef":true,"inline":true,"arguments":true,"when":true,"onExit":true,"continueOn":true,"hooks":true,"withItems":true,"withParam":true,"withSequence":true}
for _, step := range candidate {
for k := range step {
if !allowed[k] {
return fmt.Errorf(`unknown field %q in steps`, k)
}
}
} Try / catch
err := json.Unmarshal(data, &wf)
if err != nil {
var unknown [1]string
if n, _ := fmt.Sscanf(err.Error(), `json: unknown field %q`, &unknown[0]); n == 1 {
return fmt.Errorf("typo in steps field: %s", unknown[0])
}
return err
} Prevention
- Use an editor with the Argo Workflows JSON/YAML schema for autocompletion
- Run `argo lint` before applying
- Pin and match docs to your installed Argo version
When it happens
Trigger: Unmarshalling a Workflow (via kubectl apply, argo submit, or the k8s API) where a step object inside `steps` contains a JSON key that is not a WorkflowStep field, e.g. a typo like `templete` or `nam`.
Common situations: Typo in a step field name; using a field from an older/newer spec version that no longer exists; copy-pasting from documentation of a different CRD version.
Related errors
- invalid TTL
- failed to parse TypeMeta: %w
- Failed to convert the PodSpecPatch yaml to json
- Error in Unmarshalling after merge the patch
- no text to unmarshal
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/763ff3f464c3fa95.
Report an issue: GitHub.