/kind bug
Bug
When using merge2.MergeStrings with MergeOptions{ListIncreaseDirection: MergeOptionsListPrepend}, strategic merge patch directives ($patch: replace, $patch: delete) on individual associative list elements are silently ignored.
With default MergeOptions{} (Append), $patch: replace correctly replaces the matched list element. With ListPrepend, the original element remains unchanged and the replacement is dropped.
Root cause
In kyaml/yaml/walk/associative_sequence.go, setAssociativeSequenceElements() assembles the final list differently depending on the merge direction:
- Append (correct):
appendListNode(dest, itemsToBeAdded, ...); merged results from itemsToBeAdded overwrite originals in dest.
- ListPrepend (buggy):
appendListNode(itemsToBeAdded, dest, ...); the arguments are swapped for ordering, but this causes ElementSetter to overwrite already-merged items in itemsToBeAdded with the unmerged originals from dest, undoing $patch directive effects.
Reproduction
Minimal reproduction project: https://github.com/rm3l/kyaml-listprepend-bug
git clone https://github.com/rm3l/kyaml-listprepend-bug
cd kyaml-listprepend-bug
go test -v ./...
TestPatchReplaceWithDefaultMerge: PASS
TestPatchReplaceWithListPrepend: FAIL (the $patch: replace is ignored)
Versions affected
Tested and confirmed on:
sigs.k8s.io/kustomize/kyaml v0.18.1
sigs.k8s.io/kustomize/kyaml v0.19.0
sigs.k8s.io/kustomize/kyaml v0.21.0
sigs.k8s.io/kustomize/kyaml v0.21.1
- Latest master commit (313aace, 2025-05-02)
Impact
This bug prevents combining ListPrepend (for controlling list item ordering) with $patch: replace or $patch: delete (for replacing/removing individual items by merge key). The two features are independent and should compose correctly IMHO.
/kind bug
Bug
When using
merge2.MergeStringswithMergeOptions{ListIncreaseDirection: MergeOptionsListPrepend}, strategic merge patch directives ($patch: replace,$patch: delete) on individual associative list elements are silently ignored.With default
MergeOptions{}(Append),$patch: replacecorrectly replaces the matched list element. WithListPrepend, the original element remains unchanged and the replacement is dropped.Root cause
In
kyaml/yaml/walk/associative_sequence.go,setAssociativeSequenceElements()assembles the final list differently depending on the merge direction:appendListNode(dest, itemsToBeAdded, ...); merged results fromitemsToBeAddedoverwrite originals indest.appendListNode(itemsToBeAdded, dest, ...); the arguments are swapped for ordering, but this causesElementSetterto overwrite already-merged items initemsToBeAddedwith the unmerged originals fromdest, undoing$patchdirective effects.Reproduction
Minimal reproduction project: https://github.com/rm3l/kyaml-listprepend-bug
TestPatchReplaceWithDefaultMerge: PASSTestPatchReplaceWithListPrepend: FAIL (the$patch: replaceis ignored)Versions affected
Tested and confirmed on:
sigs.k8s.io/kustomize/kyamlv0.18.1sigs.k8s.io/kustomize/kyamlv0.19.0sigs.k8s.io/kustomize/kyamlv0.21.0sigs.k8s.io/kustomize/kyamlv0.21.1Impact
This bug prevents combining
ListPrepend(for controlling list item ordering) with$patch: replaceor$patch: delete(for replacing/removing individual items by merge key). The two features are independent and should compose correctly IMHO.