{"record":{"id":"8b2e574276af176f","repo":"argoproj/argo-workflows","slug":"failed-to-marshal-the-pod-spec","errorCode":null,"errorMessage":"Failed to marshal the Pod spec","messagePattern":"Failed to marshal the Pod spec","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"workflow/util/util.go","lineNumber":1682,"sourceCode":"\tstr = strings.TrimSpace(str)\n\treturn len(str) > 0 && str[0] == '{'\n}\n\nfunc ConvertYAMLToJSON(str string) (string, error) {\n\tif !IsJSONStr(str) {\n\t\tjsonStr, err := yaml.YAMLToJSON([]byte(str))\n\t\tif err != nil {\n\t\t\treturn str, err\n\t\t}\n\t\treturn string(jsonStr), nil\n\t}\n\treturn str, nil\n}\n\nfunc ApplyPodSpecPatch(podSpec apiv1.PodSpec, podSpecPatchYamls ...string) (*apiv1.PodSpec, error) {\n\tpodSpecJSON, err := json.Marshal(podSpec)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"\", \"Failed to marshal the Pod spec\")\n\t}\n\n\tfor _, podSpecPatchYaml := range podSpecPatchYamls {\n\t\t// must convert to json because PodSpec has only json tags\n\t\tpodSpecPatchJSON, convertErr := ConvertYAMLToJSON(podSpecPatchYaml)\n\t\tif convertErr != nil {\n\t\t\treturn nil, errors.Wrap(convertErr, \"\", \"Failed to convert the PodSpecPatch yaml to json\")\n\t\t}\n\n\t\t// validate the patch to be a PodSpec\n\t\tif unmarshalErr := json.Unmarshal([]byte(podSpecPatchJSON), &apiv1.PodSpec{}); unmarshalErr != nil {\n\t\t\treturn nil, fmt.Errorf(\"invalid podSpecPatch %q: %w\", podSpecPatchYaml, unmarshalErr)\n\t\t}\n\n\t\tpodSpecJSON, err = strategicpatch.StrategicMergePatch(podSpecJSON, []byte(podSpecPatchJSON), apiv1.PodSpec{})\n\t\tif err != nil {\n\t\t\treturn nil, errors.Wrap(err, \"\", \"Error occurred during strategic merge patch\")\n\t\t}","sourceCodeStart":1664,"sourceCodeEnd":1700,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/workflow/util/util.go#L1664-L1700","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Go: sanity-check the base spec marshals before patching\nif _, err := json.Marshal(podSpec); err != nil {\n\treturn fmt.Errorf(\"base podSpec is not JSON-encodable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"// Go: unwrap and report the marshal root cause\npatched, err := util.ApplyPodSpecPatch(podSpec, patchYaml)\nif err != nil && strings.Contains(err.Error(), \"Failed to marshal the Pod spec\") {\n\treturn fmt.Errorf(\"cannot patch: base PodSpec unencodable: %w\", err)\n}","preventionTips":["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."],"tags":["json","marshal","podspec"],"backgroundTag":"json-marshal-failed","analyzedSha":"35bff19146f5a6ada77468c431f2624bd577e373","analyzedAt":"2026-09-03T19:34:35.908Z","contentChangedAt":"2026-09-03T19:34:35.908Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}