From e3829ebbbb833e159926c6193e474eb9d067ef75 Mon Sep 17 00:00:00 2001 From: Philipp Born Date: Thu, 22 Jan 2026 18:27:40 +0100 Subject: [PATCH] fix(copystructure): handle nil elements in slice copying When copying slices containing nil interface{} elements, the copyValue function would panic with 'reflect: call of reflect.Value.Set on zero Value'. This occurred because reflect.ValueOf(nil) returns a zero Value that cannot be set. This issue was introduced in v4.1.0 when replacing mitchellh/copystructure with an internal implementation. The fix mirrors the existing nil handling logic used for map values. Fixes helm template panic when processing charts with YAML like: extraArgs: - Added test case to verify slice elements with nil values are properly handled during deep copy operations. Signed-off-by: Philipp Born --- internal/copystructure/copystructure.go | 10 +++++++++- internal/copystructure/copystructure_test.go | 15 +++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/internal/copystructure/copystructure.go b/internal/copystructure/copystructure.go index aa5510298..c55897aaa 100644 --- a/internal/copystructure/copystructure.go +++ b/internal/copystructure/copystructure.go @@ -89,7 +89,15 @@ func copyValue(original reflect.Value) (any, error) { } copied := reflect.MakeSlice(original.Type(), original.Len(), original.Cap()) for i := 0; i < original.Len(); i++ { - val, err := copyValue(original.Index(i)) + elem := original.Index(i) + + // Handle nil values in slices (e.g., interface{} elements that are nil) + if elem.Kind() == reflect.Interface && elem.IsNil() { + copied.Index(i).Set(elem) + continue + } + + val, err := copyValue(elem) if err != nil { return nil, err } diff --git a/internal/copystructure/copystructure_test.go b/internal/copystructure/copystructure_test.go index d1708dc75..b21af6460 100644 --- a/internal/copystructure/copystructure_test.go +++ b/internal/copystructure/copystructure_test.go @@ -113,6 +113,21 @@ func TestCopy_Slice(t *testing.T) { input[0]["key1"] = "modified" assert.Equal(t, "value1", resultSlice[0]["key1"]) }) + + t.Run("slice with nil elements", func(t *testing.T) { + input := []any{ + "value1", + nil, + "value2", + } + result, err := Copy(input) + require.NoError(t, err) + + resultSlice, ok := result.([]any) + require.True(t, ok) + assert.Equal(t, input, resultSlice) + assert.Nil(t, resultSlice[1]) + }) } func TestCopy_Map(t *testing.T) {