{"record":{"id":"d467c8ec4491ea9a","repo":"argoproj/argo-workflows","slug":"error-in-unmarshalling-after-merge-the-patch","errorCode":null,"errorMessage":"Error in Unmarshalling after merge the patch","messagePattern":"Error in Unmarshalling after merge the patch","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"workflow/util/util.go","lineNumber":1706,"sourceCode":"\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}\n\t}\n\n\tvar newPodSpec apiv1.PodSpec\n\terr = json.Unmarshal(podSpecJSON, &newPodSpec)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"\", \"Error in Unmarshalling after merge the patch\")\n\t}\n\treturn &newPodSpec, nil\n}\n\nfunc GetNodeType(tmpl *wfv1.Template) wfv1.NodeType {\n\treturn tmpl.GetNodeType()\n}\n\n// IsWindowsUNCPath checks if path is prefixed with \\\\\n// This can be used to skip any processing of paths\n// that point to SMB shares, local named pipes and local UNC path\nfunc IsWindowsUNCPath(path string, tmpl *wfv1.Template) bool {\n\tif !HasWindowsOSNodeSelector(tmpl.NodeSelector) && nruntime.GOOS != \"windows\" {\n\t\treturn false\n\t}\n\t// Check for UNC prefix \\\\\n\tif strings.HasPrefix(path, `\\\\`) {\n\t\treturn true","sourceCodeStart":1688,"sourceCodeEnd":1724,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/workflow/util/util.go#L1688-L1724","documentation":"This error is returned by the pod-spec merge helper in workflow/util when the JSON produced after applying a strategic-merge patch cannot be unmarshalled back into an apiv1.PodSpec. It means the merge-patch result is not a valid PodSpec JSON document, so Argo cannot construct the patched pod spec for the workflow step. It wraps the underlying json.Unmarshal error, which names the actual decoding problem and byte offset.","triggerScenarios":"Calling the merge-pod-spec helper (podSpec merge used when patching workflow pod specs) with a merge patch whose application yields malformed or non-PodSpec JSON; corrupted podSpecJSON input; a patch that replaces the spec with a wrong-typed structure (e.g. an array or string instead of an object).","commonSituations":"Custom mutating webhooks or external controllers producing malformed patched specs; version skew between k8s API libs causing field-type changes; manually crafted patches submitted via API/CI that serialize containers or volumes with wrong types.","solutions":["Read the wrapped underlying error: it identifies the JSON path/type that failed to decode","Print/log podSpecJSON and validate it with json.Unmarshal into a map or k8s PodSpec before calling","Fix the merge patch so the resulting document is a valid PodSpec object","Align k8s.io/api versions so PodSpec field types match between producer and consumer"],"exampleFix":"// before: patch produces e.g. `{\"containers\": \"nginx\"}` (string instead of array)\n// after: correct patch shape\npatch := []byte(`{\"spec\":{\"containers\":[{\"name\":\"main\",\"image\":\"nginx\"}]}}`)","handlingStrategy":"try-catch","validationCode":"var probe map[string]any\nif err := json.Unmarshal(podSpecJSON, &probe); err != nil {\n    return fmt.Errorf(\"podSpecJSON is not valid JSON: %w\", err)\n}","typeGuard":"func isObject(b []byte) bool {\n    var m map[string]any\n    return json.Unmarshal(b, &m) == nil && m != nil\n}","tryCatchPattern":"spec, err := mergePatchPodSpec(base, patch)\nif err != nil {\n    var uerr *errors.ArgoError\n    if stderrors.As(err, &uerr) {\n        log.Errorf(\"pod spec unmarshal failed: %v\", uerr)\n    }\n    return err\n}","preventionTips":["Validate merge-patch output JSON decodes into apiv1.PodSpec before production use","Log podSpecJSON on failure to inspect the offending bytes","Pin k8s.io/api versions across producer and consumer","Test patches against representative pod specs in CI"],"tags":["json","unmarshal","podspec","merge-patch"],"backgroundTag":"json-unmarshal-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"}