From a0d4a74c5ebe40331f571a3648315e9d8a2ec011 Mon Sep 17 00:00:00 2001 From: themavik Date: Thu, 19 Mar 2026 08:46:20 -0400 Subject: [PATCH 1/2] fix: allow null values from --values to override parent chart values Fixes #31919. Null values in override files now correctly remove parent chart defaults. Made-with: Cursor --- pkg/chart/common/util/coalesce.go | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/pkg/chart/common/util/coalesce.go b/pkg/chart/common/util/coalesce.go index 5994febbc..7b3dbe8c5 100644 --- a/pkg/chart/common/util/coalesce.go +++ b/pkg/chart/common/util/coalesce.go @@ -302,28 +302,20 @@ func coalesceTablesFullKey(printf printFn, dst, src map[string]any, prefix strin if dst == nil { return src } - // Track original non-nil src keys before modifying src - // This lets us distinguish between user nullifying a chart default vs - // user setting nil for a key not in chart defaults. - srcOriginalNonNil := make(map[string]bool) - for key, val := range src { - if val != nil { - srcOriginalNonNil[key] = true - } - } for key, val := range dst { if val == nil { - src[key] = nil + if _, inSrc := src[key]; inSrc { + src[key] = nil + } } } // Because dest has higher precedence than src, dest values override src // values. for key, val := range src { fullkey := concatPrefix(prefix, key) - if dv, ok := dst[key]; ok && !merge && dv == nil && srcOriginalNonNil[key] { - // When coalescing (not merging), if dst has nil and src has a non-nil - // value, the user is nullifying a chart default - remove the key. - // But if src also has nil (or key not in src), preserve the nil + if dv, ok := dst[key]; ok && !merge && dv == nil { + // When coalescing (not merging), if dst has nil, remove the key. + // This allows null from --values to override and remove parent chart defaults. delete(dst, key) } else if !ok { // key not in user values, preserve src value (including nil) From a8fec71650782443c529f420845c1eeaeb699ed1 Mon Sep 17 00:00:00 2001 From: themavik Date: Thu, 19 Mar 2026 08:58:49 -0400 Subject: [PATCH 2/2] test: add regression test for null values merge (#31919) Signed-off-by: themavik Made-with: Cursor --- pkg/chart/common/util/coalesce_test.go | 27 ++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/pkg/chart/common/util/coalesce_test.go b/pkg/chart/common/util/coalesce_test.go index 1d0baa84d..068b279eb 100644 --- a/pkg/chart/common/util/coalesce_test.go +++ b/pkg/chart/common/util/coalesce_test.go @@ -765,3 +765,30 @@ func TestCoalesceValuesEmptyMapWithNils(t *testing.T) { is.True(ok, "Expected data.baz key to be present but it was removed") is.Nil(data["baz"], "Expected data.baz key to be nil but it is not") } + + +// TestCoalesceTablesNullNullRegression tests regression #31919: when lower-precedence map has key with nil +// and override also sets it to null, the key should be removed from coalesced values. +func TestCoalesceTablesNullNullRegression(t *testing.T) { + tests := []struct { + name string + dst map[string]any + src map[string]any + expected map[string]any + }{ + { + name: "null values merge regression #31919", + dst: map[string]any{"key": nil}, + src: map[string]any{"key": nil}, + expected: map[string]any{}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + dst := make(map[string]any) + maps.Copy(dst, tt.dst) + CoalesceTables(dst, tt.src) + assert.Equal(t, tt.expected, dst) + }) + } +}