diff --git a/internal/fields/testdata/fields/fields.yml b/internal/fields/testdata/fields/fields.yml index 77d39fd73..1fb7459af 100644 --- a/internal/fields/testdata/fields/fields.yml +++ b/internal/fields/testdata/fields/fields.yml @@ -86,3 +86,5 @@ type: keyword normalize: - array +- name: user.group.id + type: keyword diff --git a/internal/fields/testdata/undefined-array-of-objects.json b/internal/fields/testdata/undefined-array-of-objects.json new file mode 100644 index 000000000..4a4f4a697 --- /dev/null +++ b/internal/fields/testdata/undefined-array-of-objects.json @@ -0,0 +1,12 @@ +{ + "user": { + "group": [ + { + "id": "42" + }, + { + "id": "0" + } + ] + } +} diff --git a/internal/fields/validate.go b/internal/fields/validate.go index b4fb238cd..5e41f3d55 100644 --- a/internal/fields/validate.go +++ b/internal/fields/validate.go @@ -584,7 +584,12 @@ func (v *Validator) validateScalarElement(key string, val interface{}, doc commo } if definition == nil { - return fmt.Errorf(`field "%s" is undefined`, key) + switch val.(type) { + case []any, []map[string]interface{}: + return fmt.Errorf(`field "%s" is used as array of objects, expected explicit definition with type group or nested`, key) + default: + return fmt.Errorf(`field "%s" is undefined`, key) + } } // Convert numeric keyword fields to string for validation. diff --git a/internal/fields/validate_test.go b/internal/fields/validate_test.go index 5ed37050f..a7c57ff73 100644 --- a/internal/fields/validate_test.go +++ b/internal/fields/validate_test.go @@ -148,6 +148,17 @@ func TestValidate_ipAddress(t *testing.T) { require.Empty(t, errs) } +func TestValidate_undefinedArrayOfObjects(t *testing.T) { + validator, err := CreateValidatorForDirectory("testdata", WithSpecVersion("2.0.0"), WithDisabledDependencyManagement()) + require.NoError(t, err) + require.NotNil(t, validator) + + e := readSampleEvent(t, "testdata/undefined-array-of-objects.json") + errs := validator.ValidateDocumentBody(e) + require.Len(t, errs, 1) + require.Contains(t, errs[0].Error(), `field "user.group" is used as array of objects, expected explicit definition with type group or nested`) +} + func TestValidate_WithSpecVersion(t *testing.T) { validator, err := CreateValidatorForDirectory("testdata", WithSpecVersion("2.0.0"), WithDisabledDependencyManagement()) require.NoError(t, err)