argoproj/argo-workflows · error
Error in Unmarshalling after merge the patch
Error message
Error in Unmarshalling after merge the patch
What it means
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.
Source
Thrown at workflow/util/util.go:1706
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")
}
}
var newPodSpec apiv1.PodSpec
err = json.Unmarshal(podSpecJSON, &newPodSpec)
if err != nil {
return nil, errors.Wrap(err, "", "Error in Unmarshalling after merge the patch")
}
return &newPodSpec, nil
}
func GetNodeType(tmpl *wfv1.Template) wfv1.NodeType {
return tmpl.GetNodeType()
}
// IsWindowsUNCPath checks if path is prefixed with \\
// This can be used to skip any processing of paths
// that point to SMB shares, local named pipes and local UNC path
func IsWindowsUNCPath(path string, tmpl *wfv1.Template) bool {
if !HasWindowsOSNodeSelector(tmpl.NodeSelector) && nruntime.GOOS != "windows" {
return false
}
// Check for UNC prefix \\
if strings.HasPrefix(path, `\\`) {
return trueView on GitHub (pinned to 35bff19146)
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
Example fix
// before: patch produces e.g. `{"containers": "nginx"}` (string instead of array)
// after: correct patch shape
patch := []byte(`{"spec":{"containers":[{"name":"main","image":"nginx"}]}}`) Defensive patterns
Strategy: try-catch
Validate before calling
var probe map[string]any
if err := json.Unmarshal(podSpecJSON, &probe); err != nil {
return fmt.Errorf("podSpecJSON is not valid JSON: %w", err)
} Type guard
func isObject(b []byte) bool {
var m map[string]any
return json.Unmarshal(b, &m) == nil && m != nil
} Try / catch
spec, err := mergePatchPodSpec(base, patch)
if err != nil {
var uerr *errors.ArgoError
if stderrors.As(err, &uerr) {
log.Errorf("pod spec unmarshal failed: %v", uerr)
}
return err
} Prevention
- 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
When it happens
Trigger: 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).
Common situations: 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.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
- invalid TTL
- json: unknown field "%s"
- Failed to marshal the Pod spec
- Failed to convert the PodSpecPatch yaml to json
- Error occurred during strategic merge patch
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/d467c8ec4491ea9a.
Report an issue: GitHub.