diff --git a/value/reflectcache.go b/value/reflectcache.go index 3b4a402e..75b7085c 100644 --- a/value/reflectcache.go +++ b/value/reflectcache.go @@ -84,6 +84,10 @@ func (f *FieldCacheEntry) CanOmit(fieldVal reflect.Value) bool { func (f *FieldCacheEntry) GetFrom(structVal reflect.Value) reflect.Value { // field might be nested within 'inline' structs for _, elem := range f.fieldPath { + if safeIsNil(structVal) { + // if any part of the path is nil, return the zero value for the field type + return reflect.Zero(f.fieldType) + } structVal = dereference(structVal).FieldByIndex(elem) } return structVal diff --git a/value/valuereflect_test.go b/value/valuereflect_test.go index 08b0ba14..17164981 100644 --- a/value/valuereflect_test.go +++ b/value/valuereflect_test.go @@ -290,6 +290,12 @@ func TestReflectStruct(t *testing.T) { expectedMap: map[string]interface{}{"int": int64(10), "S": "string"}, expectedUnstructured: map[string]interface{}{"int": int64(10), "S": "string"}, }, + { + name: "embeddedIsNil", + val: testEmbeddedStruct{}, + expectedMap: map[string]interface{}{"int": int64(0), "S": ""}, + expectedUnstructured: map[string]interface{}{"int": int64(0), "S": ""}, + }, } for _, tc := range cases {