argoproj/argo-workflows · error
json: unknown field
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.
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
- Error in Unmarshalling after merge the patch
- Failed to convert the PodSpecPatch yaml to json
- failed to parse TypeMeta
- invalid TTL
- 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.
Appendix: 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)