diff --git a/internal/concat.go b/internal/concat.go index fd9b8abc5..3ac6dcaf1 100644 --- a/internal/concat.go +++ b/internal/concat.go @@ -205,18 +205,30 @@ func ConcatSliceValue(val reflect.Value) (reflect.Value, error) { } func toSliceValue(vs []any) (reflect.Value, error) { - typ := reflect.TypeOf(vs[0]) + // Filter out nil elements and find the first non-nil element's type. + var nonNil []any + for _, v := range vs { + if v != nil { + nonNil = append(nonNil, v) + } + } - ret := reflect.MakeSlice(reflect.SliceOf(typ), len(vs), len(vs)) - ret.Index(0).Set(reflect.ValueOf(vs[0])) + if len(nonNil) == 0 { + // All elements are nil; return an empty []any slice. + return reflect.ValueOf([]any{}), nil + } - for i := 1; i < len(vs); i++ { - v := vs[i] + typ := reflect.TypeOf(nonNil[0]) + for i, v := range nonNil { vt := reflect.TypeOf(v) if typ != vt { return reflect.Value{}, fmt.Errorf("unexpected slice element type. Got %v, expected %v", typ, vt) } + _ = i + } + ret := reflect.MakeSlice(reflect.SliceOf(typ), len(nonNil), len(nonNil)) + for i, v := range nonNil { ret.Index(i).Set(reflect.ValueOf(v)) } diff --git a/internal/concat_test.go b/internal/concat_test.go index 12b4837bc..640a545a4 100644 --- a/internal/concat_test.go +++ b/internal/concat_test.go @@ -49,4 +49,28 @@ func TestConcat(t *testing.T) { }, }, m) }) + + t.Run("concat map with nil value in first chunk and non-nil in second", func(t *testing.T) { + c1 := map[string]any{"key": nil} + c2 := map[string]any{"key": "value"} + m, err := ConcatItems([]map[string]any{c1, c2}) + assert.Nil(t, err) + assert.Equal(t, map[string]any{"key": "value"}, m) + }) + + t.Run("concat map with non-nil value in first chunk and nil in second", func(t *testing.T) { + c1 := map[string]any{"key": "value"} + c2 := map[string]any{"key": nil} + m, err := ConcatItems([]map[string]any{c1, c2}) + assert.Nil(t, err) + assert.Equal(t, map[string]any{"key": "value"}, m) + }) + + t.Run("concat flat map with mixed nil values", func(t *testing.T) { + c1 := map[string]any{"a": nil, "b": "hello"} + c2 := map[string]any{"a": "world", "b": "hello2"} + m, err := ConcatItems([]map[string]any{c1, c2}) + assert.Nil(t, err) + assert.Equal(t, map[string]any{"a": "world", "b": "hellohello2"}, m) + }) }