argoproj/argo-workflows · error
Failed to marshal the Pod spec
Error message
Failed to marshal the Pod spec
What it means
ApplyPodSpecPatch first serializes the base apiv1.PodSpec to JSON before applying patches. If json.Marshal fails on the PodSpec (essentially only when the in-memory struct contains values unencodable to JSON, or a nil/invalid input slips through), it returns the original marshal error wrapped with the message "Failed to marshal the Pod spec". This is an internal wrapping with the caller-supplied empty code — rarely hit in practice since PodSpec marshaling is reliable.
Source
Thrown at workflow/util/util.go:1682
str = strings.TrimSpace(str)
return len(str) > 0 && str[0] == '{'
}
func ConvertYAMLToJSON(str string) (string, error) {
if !IsJSONStr(str) {
jsonStr, err := yaml.YAMLToJSON([]byte(str))
if err != nil {
return str, err
}
return string(jsonStr), nil
}
return str, nil
}
func ApplyPodSpecPatch(podSpec apiv1.PodSpec, podSpecPatchYamls ...string) (*apiv1.PodSpec, error) {
podSpecJSON, err := json.Marshal(podSpec)
if err != nil {
return nil, errors.Wrap(err, "", "Failed to marshal the Pod spec")
}
for _, podSpecPatchYaml := range podSpecPatchYamls {
// must convert to json because PodSpec has only json tags
podSpecPatchJSON, convertErr := ConvertYAMLToJSON(podSpecPatchYaml)
if convertErr != nil {
return nil, errors.Wrap(convertErr, "", "Failed to convert the PodSpecPatch yaml to json")
}
// validate the patch to be a PodSpec
if unmarshalErr := json.Unmarshal([]byte(podSpecPatchJSON), &apiv1.PodSpec{}); unmarshalErr != nil {
return nil, fmt.Errorf("invalid podSpecPatch %q: %w", podSpecPatchYaml, unmarshalErr)
}
podSpecJSON, err = strategicpatch.StrategicMergePatch(podSpecJSON, []byte(podSpecPatchJSON), apiv1.PodSpec{})
if err != nil {
return nil, errors.Wrap(err, "", "Error occurred during strategic merge patch")
}View on GitHub (pinned to 35bff19146)
Solutions
- Inspect the wrapped underlying error to identify which field fails to marshal.
- Rebuild the PodSpec from a known-good source (e.g. re-read the workflow/template rather than reusing a mutated struct).
- If you construct PodSpecs in code, validate them with json.Marshal in tests to catch unencodable fields early.
Defensive patterns
Strategy: try-catch
Validate before calling
// Go: sanity-check the base spec marshals before patching
if _, err := json.Marshal(podSpec); err != nil {
return fmt.Errorf("base podSpec is not JSON-encodable: %w", err)
} Try / catch
// Go: unwrap and report the marshal root cause
patched, err := util.ApplyPodSpecPatch(podSpec, patchYaml)
if err != nil && strings.Contains(err.Error(), "Failed to marshal the Pod spec") {
return fmt.Errorf("cannot patch: base PodSpec unencodable: %w", err)
} Prevention
- Test any code that constructs PodSpecs with a json.Marshal round-trip.
- Avoid mutating PodSpec structs with non-standard values before patching.
- Prefer building PodSpecs from templates/known-good YAML rather than incremental in-memory edits.
- Re-read the spec from the API instead of reusing long-lived mutated structs.
When it happens
Trigger: Calling ApplyPodSpecPatch with a PodSpec whose fields cannot be marshaled to JSON — e.g. a struct instance containing invalid numeric/byte values or a corrupted PodSpec built programmatically; the workflow controller applying podSpecPatch during pod creation.
Common situations: Custom controllers or test harnesses constructing PodSpecs with unsupported field values; memory corruption or misuse of the API in forked code paths; virtually never triggered by user-supplied YAML since the failure occurs before patch application.
Understand the failure class
Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.
Related errors
- Failed to convert the PodSpecPatch yaml to json
- Error occurred during strategic merge patch
- Error in Unmarshalling after merge the patch
- invalid TTL
- error converting %s: %w
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/8b2e574276af176f.
Report an issue: GitHub.